X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=4072464558ea436cfa6ca8cd784b64c41becc8ed;hb=7ed1acafa0b5d135342f9dcc0eb0387dff95005a;hp=baf6b67d0963c3ff2c77d711e4afc8f588eff155;hpb=ede5f15146ae45f4c017f5701629a4fa04ef2beb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index baf6b67d09..4072464558 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -43,7 +43,6 @@ #include "record-full.h" #include "auxv.h" -#include "libbfd.h" /* for bfd_default_set_arch_mach */ #include "coff/internal.h" /* for libcoff.h */ #include "libcoff.h" /* for xcoff_data */ #include "coff/xcoff.h" @@ -63,6 +62,10 @@ #include "frame-unwind.h" #include "frame-base.h" +#include "ax.h" +#include "ax-gdb.h" +#include + #include "features/rs6000/powerpc-32.c" #include "features/rs6000/powerpc-altivec32.c" #include "features/rs6000/powerpc-vsx32.c" @@ -103,6 +106,9 @@ && (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; @@ -328,7 +334,7 @@ init_sim_regno_table (struct gdbarch *arch) set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum); /* spefscr is a special-purpose register, so the code below handles it. */ -#ifdef WITH_SIM +#ifdef WITH_PPC_SIM /* Now handle all special-purpose registers. Verify that they haven't mistakenly been assigned numbers by any of the above code. */ @@ -964,18 +970,11 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, /* Sequence of bytes for breakpoint instruction. */ -static const unsigned char * -rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr, - int *bp_size) -{ - static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; - static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; - *bp_size = 4; - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) - return big_breakpoint; - else - return little_breakpoint; -} +constexpr gdb_byte big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; +constexpr gdb_byte little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; + +typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint) + rs6000_breakpoint; /* Instruction masks for displaced stepping. */ #define BRANCH_MASK 0xfc000000 @@ -987,12 +986,33 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr, /* Instruction masks used during single-stepping of atomic sequences. */ -#define LWARX_MASK 0xfc0007fe +#define LOAD_AND_RESERVE_MASK 0xfc0007fe #define LWARX_INSTRUCTION 0x7c000028 #define LDARX_INSTRUCTION 0x7c0000A8 -#define STWCX_MASK 0xfc0007ff +#define LBARX_INSTRUCTION 0x7c000068 +#define LHARX_INSTRUCTION 0x7c0000e8 +#define LQARX_INSTRUCTION 0x7c000228 +#define STORE_CONDITIONAL_MASK 0xfc0007ff #define STWCX_INSTRUCTION 0x7c00012d #define STDCX_INSTRUCTION 0x7c0001ad +#define STBCX_INSTRUCTION 0x7c00056d +#define STHCX_INSTRUCTION 0x7c0005ad +#define STQCX_INSTRUCTION 0x7c00016d + +/* Check if insn is one of the Load And Reserve instructions used for atomic + sequences. */ +#define IS_LOAD_AND_RESERVE_INSN(insn) ((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \ + || (insn & LOAD_AND_RESERVE_MASK) == LDARX_INSTRUCTION \ + || (insn & LOAD_AND_RESERVE_MASK) == LBARX_INSTRUCTION \ + || (insn & LOAD_AND_RESERVE_MASK) == LHARX_INSTRUCTION \ + || (insn & LOAD_AND_RESERVE_MASK) == LQARX_INSTRUCTION) +/* Check if insn is one of the Store Conditional instructions used for atomic + sequences. */ +#define IS_STORE_CONDITIONAL_INSN(insn) ((insn & STORE_CONDITIONAL_MASK) == STWCX_INSTRUCTION \ + || (insn & STORE_CONDITIONAL_MASK) == STDCX_INSTRUCTION \ + || (insn & STORE_CONDITIONAL_MASK) == STBCX_INSTRUCTION \ + || (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. */ @@ -1012,9 +1032,8 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch, insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order); - /* Assume all atomic sequences start with a lwarx/ldarx instruction. */ - if ((insn & LWARX_MASK) == LWARX_INSTRUCTION - || (insn & LWARX_MASK) == LDARX_INSTRUCTION) + /* Assume all atomic sequences start with a Load and Reserve instruction. */ + if (IS_LOAD_AND_RESERVE_INSN (insn)) { if (debug_displaced) { @@ -1142,18 +1161,16 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch, return 1; } -/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX - instruction and ending with a STWCX/STDCX instruction. If such a sequence - is found, attempt to step through it. A breakpoint is placed at the end of - the sequence. */ - -int -ppc_deal_with_atomic_sequence (struct frame_info *frame) +/* Checks for an atomic sequence of instructions beginning with a + 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. */ +std::vector +ppc_deal_with_atomic_sequence (struct regcache *regcache) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - CORE_ADDR pc = get_frame_pc (frame); + CORE_ADDR pc = regcache_read_pc (regcache); CORE_ADDR breaks[2] = {-1, -1}; CORE_ADDR loc = pc; CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */ @@ -1162,13 +1179,11 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) int index; int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ const int atomic_sequence_length = 16; /* Instruction sequence length. */ - int opcode; /* Branch instruction's OPcode. */ int bc_insn_count = 0; /* Conditional branch instruction count. */ - /* Assume all atomic sequences start with a lwarx/ldarx instruction. */ - if ((insn & LWARX_MASK) != LWARX_INSTRUCTION - && (insn & LWARX_MASK) != LDARX_INSTRUCTION) - return 0; + /* Assume all atomic sequences start with a Load And Reserve instruction. */ + if (!IS_LOAD_AND_RESERVE_INSN (insn)) + return {}; /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ @@ -1186,8 +1201,8 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) 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; @@ -1198,15 +1213,14 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) last_breakpoint++; } - if ((insn & STWCX_MASK) == STWCX_INSTRUCTION - || (insn & STWCX_MASK) == STDCX_INSTRUCTION) + if (IS_STORE_CONDITIONAL_INSN (insn)) break; } - /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */ - if ((insn & STWCX_MASK) != STWCX_INSTRUCTION - && (insn & STWCX_MASK) != STDCX_INSTRUCTION) - return 0; + /* Assume that the atomic sequence ends with a Store Conditional + instruction. */ + if (!IS_STORE_CONDITIONAL_INSN (insn)) + return {}; closing_insn = loc; loc += PPC_INSN_SIZE; @@ -1222,11 +1236,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) || (breaks[1] >= pc && breaks[1] <= closing_insn))) last_breakpoint = 0; - /* Effectively inserts the breakpoints. */ + std::vector next_pcs; + for (index = 0; index <= last_breakpoint; index++) - insert_single_step_breakpoint (gdbarch, aspace, breaks[index]); + next_pcs.push_back (breaks[index]); - return 1; + return next_pcs; } @@ -2184,7 +2199,7 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) CORE_ADDR post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr); if (post_prologue_pc != 0) - return max (pc, post_prologue_pc); + return std::max (pc, post_prologue_pc); } /* Can't determine prologue from the symbol table, need to examine @@ -2919,6 +2934,62 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_register_name (gdbarch, reg_nr), reg_nr); } +static int +rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_ev0_regnum; + ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index); + ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index); + } + else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_dl0_regnum; + ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index); + ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1); + } + else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_vsr0_regnum; + if (reg_index > 31) + { + ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32); + } + else + { + ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index); + ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index); + } + } + else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + { + int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index); + } + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_collect: " + "called on unexpected register '%s' (%d)"), + gdbarch_register_name (gdbarch, reg_nr), reg_nr); + return 0; +} + + +static void +rs6000_gen_return_address (struct gdbarch *gdbarch, + struct agent_expr *ax, struct axs_value *value, + CORE_ADDR scope) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + value->type = register_type (gdbarch, tdep->ppc_lr_regnum); + value->kind = axs_lvalue_register; + value->u.reg = tdep->ppc_lr_regnum; +} + + /* Convert a DBX STABS register number to a GDB register number. */ static int rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) @@ -3076,10 +3147,10 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p) 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; @@ -3144,7 +3215,7 @@ static struct variant variants[] = {"rs2", "IBM POWER RS2", bfd_arch_rs6000, bfd_mach_rs6k_rs2, &tdesc_rs6000}, - {0, 0, 0, 0, 0} + {0, 0, (enum bfd_architecture) 0, 0, 0} }; /* Return the variant corresponding to architecture ARCH and machine number @@ -3191,6 +3262,13 @@ struct rs6000_frame_cache CORE_ADDR base; CORE_ADDR initial_sp; struct trad_frame_saved_reg *saved_regs; + + /* Set BASE_P to true if this frame cache is properly initialized. + Otherwise set to false because some registers or memory cannot + collected. */ + int base_p; + /* Cache PC for building unavailable frame. */ + CORE_ADDR pc; }; static struct rs6000_frame_cache * @@ -3202,27 +3280,39 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct rs6000_framedata fdata; int wordsize = tdep->wordsize; - CORE_ADDR func, pc; + CORE_ADDR func = 0, pc = 0; if ((*this_cache) != NULL) return (struct rs6000_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); (*this_cache) = cache; + cache->pc = 0; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - func = get_frame_func (this_frame); - pc = get_frame_pc (this_frame); - skip_prologue (gdbarch, func, pc, &fdata); - - /* Figure out the parent's stack pointer. */ - - /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most - address of the current frame. Things might be easier if the - ->frame pointed to the outer-most address of the frame. In - the mean time, the address of the prev frame is used as the - base address of this frame. */ - cache->base = get_frame_register_unsigned - (this_frame, gdbarch_sp_regnum (gdbarch)); + TRY + { + func = get_frame_func (this_frame); + cache->pc = func; + pc = get_frame_pc (this_frame); + skip_prologue (gdbarch, func, pc, &fdata); + + /* Figure out the parent's stack pointer. */ + + /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most + address of the current frame. Things might be easier if the + ->frame pointed to the outer-most address of the frame. In + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); + } + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return (struct rs6000_frame_cache *) (*this_cache); + } + END_CATCH /* If the function appears to be frameless, check a couple of likely indicators that we have simply failed to find the frame setup. @@ -3258,10 +3348,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) if (!fdata.frameless) { /* Frameless really means stackless. */ - LONGEST backchain; + ULONGEST backchain; - if (safe_read_memory_integer (cache->base, wordsize, - byte_order, &backchain)) + if (safe_read_memory_unsigned_integer (cache->base, wordsize, + byte_order, &backchain)) cache->base = (CORE_ADDR) backchain; } @@ -3371,6 +3461,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->initial_sp = get_frame_register_unsigned (this_frame, fdata.alloca_reg); + cache->base_p = 1; return cache; } @@ -3380,6 +3471,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache, { struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); + + if (!info->base_p) + { + (*this_id) = frame_id_build_unavailable_stack (info->pc); + return; + } + /* This marks the outermost frame. */ if (info->base == 0) return; @@ -3732,6 +3830,7 @@ bfd_uses_spe_extensions (bfd *abfd) #define PPC_T(insn) PPC_FIELD (insn, 6, 5) #define PPC_D(insn) PPC_SEXT (PPC_FIELD (insn, 16, 16), 16) #define PPC_DS(insn) PPC_SEXT (PPC_FIELD (insn, 16, 14), 14) +#define PPC_DQ(insn) PPC_SEXT (PPC_FIELD (insn, 16, 12), 12) #define PPC_BIT(insn,n) ((insn & (1 << (31 - (n)))) ? 1 : 0) #define PPC_OE(insn) PPC_BIT (insn, 21) #define PPC_RC(insn) PPC_BIT (insn, 31) @@ -3779,6 +3878,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int ext = PPC_FIELD (insn, 21, 11); + int vra = PPC_FIELD (insn, 11, 5); switch (ext & 0x3f) { @@ -3790,6 +3890,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, /* FALL-THROUGH */ case 42: /* Vector Select */ case 43: /* Vector Permute */ + case 59: /* Vector Permute Right-indexed */ case 44: /* Vector Shift Left Double by Octet Immediate */ case 45: /* Vector Permute and Exclusive-OR */ case 60: /* Vector Add Extended Unsigned Quadword Modulo */ @@ -3797,6 +3898,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, case 62: /* Vector Subtract Extended Unsigned Quadword Modulo */ case 63: /* Vector Subtract Extended & write Carry Unsigned Quadword */ case 34: /* Vector Multiply-Low-Add Unsigned Halfword Modulo */ + case 35: /* Vector Multiply-Sum Unsigned Doubleword Modulo */ case 36: /* Vector Multiply-Sum Unsigned Byte Modulo */ case 37: /* Vector Multiply-Sum Mixed Byte Modulo */ case 38: /* Vector Multiply-Sum Unsigned Halfword Modulo */ @@ -3806,14 +3908,37 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + PPC_VRT (insn)); return 0; + + case 48: /* Multiply-Add High Doubleword */ + case 49: /* Multiply-Add High Doubleword Unsigned */ + case 51: /* Multiply-Add Low Doubleword */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; } switch ((ext & 0x1ff)) { + case 385: + if (vra != 0 /* Decimal Convert To Signed Quadword */ + && vra != 2 /* Decimal Convert From Signed Quadword */ + && vra != 4 /* Decimal Convert To Zoned */ + && vra != 5 /* Decimal Convert To National */ + && vra != 6 /* Decimal Convert From Zoned */ + && vra != 7 /* Decimal Convert From National */ + && vra != 31) /* Decimal Set Sign */ + break; /* 5.16 Decimal Integer Arithmetic Instructions */ case 1: /* Decimal Add Modulo */ case 65: /* Decimal Subtract Modulo */ + case 193: /* Decimal Shift */ + case 129: /* Decimal Unsigned Shift */ + case 449: /* Decimal Shift and Round */ + + case 257: /* Decimal Truncate */ + case 321: /* Decimal Unsigned Truncate */ + /* Bit-21 should be set. */ if (!PPC_BIT (insn, 21)) break; @@ -3843,6 +3968,12 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, case 198: /* Vector Compare Equal To Single-Precision */ case 454: /* Vector Compare Greater Than or Equal To Single-Precision */ case 710: /* Vector Compare Greater Than Single-Precision */ + case 7: /* Vector Compare Not Equal Byte */ + case 71: /* Vector Compare Not Equal Halfword */ + case 135: /* Vector Compare Not Equal Word */ + case 263: /* Vector Compare Not Equal or Zero Byte */ + case 327: /* Vector Compare Not Equal or Zero Halfword */ + case 391: /* Vector Compare Not Equal or Zero Word */ if (PPC_Rc (insn)) record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, @@ -3850,6 +3981,38 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, return 0; } + if (ext == 1538) + { + switch (vra) + { + case 0: /* Vector Count Leading Zero Least-Significant Bits + Byte */ + case 1: /* Vector Count Trailing Zero Least-Significant Bits + Byte */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; + + case 6: /* Vector Negate Word */ + case 7: /* Vector Negate Doubleword */ + case 8: /* Vector Parity Byte Word */ + case 9: /* Vector Parity Byte Doubleword */ + case 10: /* Vector Parity Byte Quadword */ + case 16: /* Vector Extend Sign Byte To Word */ + case 17: /* Vector Extend Sign Halfword To Word */ + case 24: /* Vector Extend Sign Byte To Doubleword */ + case 25: /* Vector Extend Sign Halfword To Doubleword */ + case 26: /* Vector Extend Sign Word To Doubleword */ + case 28: /* Vector Count Trailing Zeros Byte */ + case 29: /* Vector Count Trailing Zeros Halfword */ + case 30: /* Vector Count Trailing Zeros Word */ + case 31: /* Vector Count Trailing Zeros Doubleword */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_vr0_regnum + PPC_VRT (insn)); + return 0; + } + } + switch (ext) { case 142: /* Vector Pack Unsigned Halfword Unsigned Saturate */ @@ -4021,10 +4184,44 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, case 1923: /* Vector Population Count Word */ case 1987: /* Vector Population Count Doubleword */ case 1356: /* Vector Bit Permute Quadword */ + case 1484: /* Vector Bit Permute Doubleword */ + case 513: /* Vector Multiply-by-10 Unsigned Quadword */ + case 1: /* Vector Multiply-by-10 & write Carry Unsigned + Quadword */ + case 577: /* Vector Multiply-by-10 Extended Unsigned Quadword */ + case 65: /* Vector Multiply-by-10 Extended & write Carry + Unsigned Quadword */ + case 1027: /* Vector Absolute Difference Unsigned Byte */ + case 1091: /* Vector Absolute Difference Unsigned Halfword */ + case 1155: /* Vector Absolute Difference Unsigned Word */ + case 1796: /* Vector Shift Right Variable */ + case 1860: /* Vector Shift Left Variable */ + case 133: /* Vector Rotate Left Word then Mask Insert */ + case 197: /* Vector Rotate Left Doubleword then Mask Insert */ + case 389: /* Vector Rotate Left Word then AND with Mask */ + case 453: /* Vector Rotate Left Doubleword then AND with Mask */ + case 525: /* Vector Extract Unsigned Byte */ + case 589: /* Vector Extract Unsigned Halfword */ + case 653: /* Vector Extract Unsigned Word */ + case 717: /* Vector Extract Doubleword */ + case 781: /* Vector Insert Byte */ + case 845: /* Vector Insert Halfword */ + case 909: /* Vector Insert Word */ + case 973: /* Vector Insert Doubleword */ record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + PPC_VRT (insn)); return 0; + case 1549: /* Vector Extract Unsigned Byte Left-Indexed */ + case 1613: /* Vector Extract Unsigned Halfword Left-Indexed */ + case 1677: /* Vector Extract Unsigned Word Left-Indexed */ + case 1805: /* Vector Extract Unsigned Byte Right-Indexed */ + case 1869: /* Vector Extract Unsigned Halfword Right-Indexed */ + case 1933: /* Vector Extract Unsigned Word Right-Indexed */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; + case 1604: /* Move To Vector Status and Control Register */ record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM); return 0; @@ -4032,6 +4229,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache, record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + PPC_VRT (insn)); return 0; + case 833: /* Decimal Copy Sign */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_vr0_regnum + PPC_VRT (insn)); + record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); + return 0; } fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x " @@ -4049,6 +4251,14 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int ext = PPC_EXTOP (insn); + switch (ext & 0x01f) + { + case 2: /* Add PC Immediate Shifted */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; + } + switch (ext) { case 0: /* Move Condition Register Field */ @@ -4154,6 +4364,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, return 0; } + if ((ext & 0xff) == 170) + { + /* Add Extended using alternate carry bits */ + record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum); + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; + } + switch (ext) { case 78: /* Determine Leftmost Zero Byte */ @@ -4172,6 +4391,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 302: /* Move From Branch History Rolling Buffer */ case 339: /* Move From Special Purpose Register */ case 371: /* Move From Time Base [Phased-Out] */ + case 309: /* Load Doubleword Monitored Indexed */ + case 128: /* Set Boolean */ + case 755: /* Deliver A Random Number */ record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + PPC_RT (insn)); return 0; @@ -4188,6 +4410,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 282: /* Convert Declets To Binary Coded Decimal */ case 314: /* Convert Binary Coded Decimal To Declets */ case 508: /* Compare bytes */ + case 307: /* Move From VSR Lower Doubleword */ record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + PPC_RA (insn)); return 0; @@ -4206,6 +4429,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 32: /* Compare logical */ case 144: /* Move To Condition Register Fields */ /* Move To One Condition Register Field */ + case 192: /* Compare Ranged Byte */ + case 224: /* Compare Equal Byte */ + case 576: /* Move XER to CR Extended */ + case 902: /* Paste (should always fail due to single-stepping and + the memory location might not be accessible, so + record only CR) */ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); return 0; @@ -4232,6 +4461,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 790: /* Load Halfword Byte-Reverse Indexed */ case 534: /* Load Word Byte-Reverse Indexed */ case 532: /* Load Doubleword Byte-Reverse Indexed */ + case 582: /* Load Word Atomic */ + case 614: /* Load Doubleword Atomic */ + case 265: /* Modulo Unsigned Doubleword */ + case 777: /* Modulo Signed Doubleword */ + case 267: /* Modulo Unsigned Word */ + case 779: /* Modulo Signed Word */ record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + PPC_RT (insn)); return 0; @@ -4310,6 +4545,16 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 844: /* Load VSX Vector Doubleword*2 Indexed */ case 332: /* Load VSX Vector Doubleword & Splat Indexed */ case 780: /* Load VSX Vector Word*4 Indexed */ + case 268: /* Load VSX Vector Indexed */ + case 364: /* Load VSX Vector Word & Splat Indexed */ + case 812: /* Load VSX Vector Halfword*8 Indexed */ + case 876: /* Load VSX Vector Byte*16 Indexed */ + case 269: /* Load VSX Vector with Length */ + case 301: /* Load VSX Vector Left-justified with Length */ + case 781: /* Load VSX Scalar as Integer Byte & Zero Indexed */ + case 813: /* Load VSX Scalar as Integer Halfword & Zero Indexed */ + case 403: /* Move To VSR Word & Splat */ + case 435: /* Move To VSR Double Doubleword */ ppc_record_vsr (regcache, tdep, PPC_XT (insn)); return 0; @@ -4331,6 +4576,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 922: /* Extend Sign Halfword */ case 954: /* Extend Sign Byte */ case 986: /* Extend Sign Word */ + case 538: /* Count Trailing Zeros Word */ + case 570: /* Count Trailing Zeros Doubleword */ + case 890: /* Extend-Sign Word and Shift Left Immediate (445) */ + case 890 | 1: /* Extend-Sign Word and Shift Left Immediate (445) */ if (PPC_RC (insn)) record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, @@ -4373,6 +4622,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 727: /* Store Floating-Point Double Indexed */ case 919: /* Store Floating-Point Double Pair Indexed */ case 983: /* Store Floating-Point as Integer Word Indexed */ + case 396: /* Store VSX Vector Indexed */ + case 940: /* Store VSX Vector Halfword*8 Indexed */ + case 1004: /* Store VSX Vector Byte*16 Indexed */ + case 909: /* Store VSX Scalar as Integer Byte Indexed */ + case 941: /* Store VSX Scalar as Integer Halfword Indexed */ if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182) record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); @@ -4402,6 +4656,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 135: /* Store Vector Element Byte Indexed */ case 215: /* Store Byte Indexed */ case 694: /* Store Byte Conditional Indexed */ + case 909: /* Store VSX Scalar as Integer Byte Indexed */ size = 1; break; case 439: /* Store Halfword with Update Indexed */ @@ -4409,6 +4664,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 407: /* Store Halfword Indexed */ case 726: /* Store Halfword Conditional Indexed */ case 918: /* Store Halfword Byte-Reverse Indexed */ + case 941: /* Store VSX Scalar as Integer Halfword Indexed */ size = 2; break; case 181: /* Store Doubleword with Update Indexed */ @@ -4426,6 +4682,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 231: /* Store Vector Indexed */ case 487: /* Store Vector Indexed LRU */ case 919: /* Store Floating-Point Double Pair Indexed */ + case 396: /* Store VSX Vector Indexed */ + case 940: /* Store VSX Vector Halfword*8 Indexed */ + case 1004: /* Store VSX Vector Byte*16 Indexed */ size = 16; break; default: @@ -4452,10 +4711,47 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, record_full_arch_list_add_mem (addr, size); return 0; + case 397: /* Store VSX Vector with Length */ + case 429: /* Store VSX Vector Left-justified with Length */ + ra = 0; + if (PPC_RA (insn) != 0) + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), &ra); + ea = ra; + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RB (insn), &rb); + /* Store up to 16 bytes. */ + nb = (rb & 0xff) > 16 ? 16 : (rb & 0xff); + if (nb > 0) + record_full_arch_list_add_mem (ea, nb); + return 0; + + case 710: /* Store Word Atomic */ + case 742: /* Store Doubleword Atomic */ + ra = 0; + if (PPC_RA (insn) != 0) + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), &ra); + ea = ra; + switch (ext) + { + case 710: /* Store Word Atomic */ + size = 8; + break; + case 742: /* Store Doubleword Atomic */ + size = 16; + break; + default: + gdb_assert (0); + } + record_full_arch_list_add_mem (ea, size); + return 0; + case 725: /* Store String Word Immediate */ ra = 0; if (PPC_RA (insn) != 0) - regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra); + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), &ra); ea += ra; nb = PPC_NB (insn); @@ -4469,7 +4765,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 661: /* Store String Word Indexed */ ra = 0; if (PPC_RA (insn) != 0) - regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra); + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), &ra); ea += ra; regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer); @@ -4477,7 +4774,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, if (nb != 0) { - regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb); + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RB (insn), + &rb); ea += rb; record_full_arch_list_add_mem (ea, nb); } @@ -4517,6 +4816,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 430: /* Clear BHRB */ case 598: /* Synchronize */ case 62: /* Wait for Interrupt */ + case 30: /* Wait */ case 22: /* Instruction Cache Block Touch */ case 854: /* Enforce In-order Execution of I/O */ case 246: /* Data Cache Block Touch for Store */ @@ -4525,27 +4825,30 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, case 278: /* Data Cache Block Touch */ case 758: /* Data Cache Block Allocate */ case 982: /* Instruction Cache Block Invalidate */ + case 774: /* Copy */ + case 838: /* CP_Abort */ return 0; case 654: /* Transaction Begin */ case 686: /* Transaction End */ - case 718: /* Transaction Check */ case 750: /* Transaction Suspend or Resume */ case 782: /* Transaction Abort Word Conditional */ case 814: /* Transaction Abort Doubleword Conditional */ case 846: /* Transaction Abort Word Conditional Immediate */ case 878: /* Transaction Abort Doubleword Conditional Immediate */ case 910: /* Transaction Abort */ - fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. " - "%08x at %s, 31-%d.\n", - insn, paddress (gdbarch, addr), ext); - return -1; + record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum); + /* FALL-THROUGH */ + case 718: /* Transaction Check */ + record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); + return 0; case 1014: /* Data Cache Block set to Zero */ if (target_auxv_search (¤t_target, AT_DCACHEBSIZE, &at_dcsz) <= 0 || at_dcsz == 0) at_dcsz = 128; /* Assume 128-byte cache line size (POWER8) */ + ra = 0; if (PPC_RA (insn) != 0) regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum + PPC_RA (insn), &ra); @@ -4623,6 +4926,7 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache, case 226: /* DFP Test Data Group */ case 642: /* DFP Compare Unordered */ case 674: /* DFP Test Significance */ + case 675: /* DFP Test Significance Immediate */ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); return 0; @@ -4722,7 +5026,16 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, case 217: /* ditto */ case 104: /* VSX Vector Subtract Double-Precision */ case 72: /* VSX Vector Subtract Single-Precision */ + case 128: /* VSX Scalar Maximum Type-C Double-Precision */ + case 136: /* VSX Scalar Minimum Type-C Double-Precision */ + case 144: /* VSX Scalar Maximum Type-J Double-Precision */ + case 152: /* VSX Scalar Minimum Type-J Double-Precision */ + case 3: /* VSX Scalar Compare Equal Double-Precision */ + case 11: /* VSX Scalar Compare Greater Than Double-Precision */ + case 19: /* VSX Scalar Compare Greater Than or Equal + Double-Precision */ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ case 240: /* VSX Vector Copy Sign Double-Precision */ case 208: /* VSX Vector Copy Sign Single-Precision */ case 130: /* VSX Logical AND */ @@ -4743,6 +5056,14 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, case 2 | 0x20: /* VSX Shift Left Double by Word Immediate (SHW=1) */ case 2 | 0x40: /* VSX Shift Left Double by Word Immediate (SHW=2) */ case 2 | 0x60: /* VSX Shift Left Double by Word Immediate (SHW=3) */ + case 216: /* VSX Vector Insert Exponent Single-Precision */ + case 248: /* VSX Vector Insert Exponent Double-Precision */ + case 26: /* VSX Vector Permute */ + case 58: /* VSX Vector Permute Right-indexed */ + case 213: /* VSX Vector Test Data Class Single-Precision (DC=0) */ + case 213 | 0x8: /* VSX Vector Test Data Class Single-Precision (DC=1) */ + case 245: /* VSX Vector Test Data Class Double-Precision (DC=0) */ + case 245 | 0x8: /* VSX Vector Test Data Class Double-Precision (DC=1) */ ppc_record_vsr (regcache, tdep, PPC_XT (insn)); return 0; @@ -4754,6 +5075,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, case 35: /* VSX Scalar Compare Unordered Double-Precision */ case 43: /* VSX Scalar Compare Ordered Double-Precision */ + case 59: /* VSX Scalar Compare Exponents Double-Precision */ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); return 0; @@ -4900,6 +5222,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, case 203: /* VSX Vector Square Root Double-Precision */ case 139: /* VSX Vector Square Root Single-Precision */ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ case 345: /* VSX Scalar Absolute Value Double-Precision */ case 267: /* VSX Scalar Convert Scalar Single-Precision to Vector Single-Precision format Non-signalling */ @@ -4914,9 +5237,15 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, case 505: /* VSX Vector Negate Double-Precision */ case 441: /* VSX Vector Negate Single-Precision */ case 164: /* VSX Splat Word */ + case 165: /* VSX Vector Extract Unsigned Word */ + case 181: /* VSX Vector Insert Word */ ppc_record_vsr (regcache, tdep, PPC_XT (insn)); return 0; + case 298: /* VSX Scalar Test Data Class Single-Precision */ + case 362: /* VSX Scalar Test Data Class Double-Precision */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ case 106: /* VSX Scalar Test for software Square Root Double-Precision */ case 234: /* VSX Vector Test for software Square Root @@ -4925,6 +5254,60 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, Single-Precision */ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); return 0; + + case 347: + switch (PPC_FIELD (insn, 11, 5)) + { + case 0: /* VSX Scalar Extract Exponent Double-Precision */ + case 1: /* VSX Scalar Extract Significand Double-Precision */ + record_full_arch_list_add_reg (regcache, + tdep->ppc_gp0_regnum + PPC_RT (insn)); + return 0; + case 16: /* VSX Scalar Convert Half-Precision format to + Double-Precision format */ + case 17: /* VSX Scalar round & Convert Double-Precision format + to Half-Precision format */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + ppc_record_vsr (regcache, tdep, PPC_XT (insn)); + return 0; + } + break; + + case 475: + switch (PPC_FIELD (insn, 11, 5)) + { + case 24: /* VSX Vector Convert Half-Precision format to + Single-Precision format */ + case 25: /* VSX Vector round and Convert Single-Precision format + to Half-Precision format */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ + case 0: /* VSX Vector Extract Exponent Double-Precision */ + case 1: /* VSX Vector Extract Significand Double-Precision */ + case 7: /* VSX Vector Byte-Reverse Halfword */ + case 8: /* VSX Vector Extract Exponent Single-Precision */ + case 9: /* VSX Vector Extract Significand Single-Precision */ + case 15: /* VSX Vector Byte-Reverse Word */ + case 23: /* VSX Vector Byte-Reverse Doubleword */ + case 31: /* VSX Vector Byte-Reverse Quadword */ + ppc_record_vsr (regcache, tdep, PPC_XT (insn)); + return 0; + } + break; + } + + switch (ext) + { + case 360: /* VSX Vector Splat Immediate Byte */ + if (PPC_FIELD (insn, 11, 2) == 0) + { + ppc_record_vsr (regcache, tdep, PPC_XT (insn)); + return 0; + } + break; + case 918: /* VSX Scalar Insert Exponent Double-Precision */ + ppc_record_vsr (regcache, tdep, PPC_XT (insn)); + return 0; } if (((ext >> 3) & 0x3) == 3) /* VSX Select */ @@ -4938,6 +5321,65 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache, return -1; } +/* Parse and record instructions of primary opcode-61 at ADDR. + Return 0 if successful. */ + +static int +ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache, + CORE_ADDR addr, uint32_t insn) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ULONGEST ea = 0; + int size; + + switch (insn & 0x3) + { + case 0: /* Store Floating-Point Double Pair */ + case 2: /* Store VSX Scalar Doubleword */ + case 3: /* Store VSX Scalar Single */ + if (PPC_RA (insn) != 0) + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), + &ea); + ea += PPC_DS (insn) << 2; + switch (insn & 0x3) + { + case 0: /* Store Floating-Point Double Pair */ + size = 16; + break; + case 2: /* Store VSX Scalar Doubleword */ + size = 8; + break; + case 3: /* Store VSX Scalar Single */ + size = 4; + break; + default: + gdb_assert (0); + } + record_full_arch_list_add_mem (ea, size); + return 0; + } + + switch (insn & 0x7) + { + case 1: /* Load VSX Vector */ + ppc_record_vsr (regcache, tdep, PPC_XT (insn)); + return 0; + case 5: /* Store VSX Vector */ + if (PPC_RA (insn) != 0) + regcache_raw_read_unsigned (regcache, + tdep->ppc_gp0_regnum + PPC_RA (insn), + &ea); + ea += PPC_DQ (insn) << 4; + record_full_arch_list_add_mem (ea, 16); + return 0; + } + + fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x " + "at %s.\n", insn, paddress (gdbarch, addr)); + return -1; +} + /* Parse and record instructions of primary opcode-63 at ADDR. Return 0 if successful. */ @@ -4974,6 +5416,17 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *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; + } + + switch (ext & 0xff) + { + case 5: /* VSX Scalar Round to Quad-Precision Integer */ + case 37: /* VSX Scalar Round Quad-Precision to Double-Extended + Precision */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32); + return 0; } switch (ext) @@ -5005,6 +5458,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, case 226: /* DFP Test Data Group Quad */ case 642: /* DFP Compare Unordered Quad */ case 674: /* DFP Test Significance Quad */ + case 675: /* DFP Test Significance Immediate Quad */ record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); return 0; @@ -5026,7 +5480,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, if (PPC_RC (insn)) record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); - break; + return 0; case 354: /* DFP Extract Biased Exponent Quad */ record_full_arch_list_add_reg (regcache, @@ -5061,7 +5515,26 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); return 0; - case 583: /* Move From FPSCR */ + case 583: + switch (PPC_FIELD (insn, 11, 5)) + { + case 1: /* Move From FPSCR & Clear Enables */ + case 20: /* Move From FPSCR Control & set DRN */ + case 21: /* Move From FPSCR Control & set DRN Immediate */ + case 22: /* Move From FPSCR Control & set RN */ + case 23: /* Move From FPSCR Control & set RN Immediate */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + case 0: /* Move From FPSCR */ + case 24: /* Move From FPSCR Lightweight */ + if (PPC_FIELD (insn, 11, 5) == 0 && PPC_RC (insn)) + record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); + record_full_arch_list_add_reg (regcache, + tdep->ppc_fp0_regnum + + PPC_FRT (insn)); + return 0; + } + break; + case 8: /* Floating Copy Sign */ case 40: /* Floating Negate */ case 72: /* Floating Move Register */ @@ -5086,11 +5559,15 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, if (PPC_RC (insn)) record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); - break; + return 0; case 0: /* Floating Compare Unordered */ case 32: /* Floating Compare Ordered */ case 64: /* Move to Condition Register from FPSCR */ + case 132: /* VSX Scalar Compare Ordered Quad-Precision */ + case 164: /* VSX Scalar Compare Exponents Quad-Precision */ + case 644: /* VSX Scalar Compare Unordered Quad-Precision */ + case 708: /* VSX Scalar Test Data Class Quad-Precision */ record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); /* FALL-THROUGH */ case 128: /* Floating Test for software Divide */ @@ -5098,10 +5575,65 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache, record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); return 0; + case 4: /* VSX Scalar Add Quad-Precision */ + case 36: /* VSX Scalar Multiply Quad-Precision */ + case 388: /* VSX Scalar Multiply-Add Quad-Precision */ + case 420: /* VSX Scalar Multiply-Subtract Quad-Precision */ + case 452: /* VSX Scalar Negative Multiply-Add Quad-Precision */ + case 484: /* VSX Scalar Negative Multiply-Subtract + Quad-Precision */ + case 516: /* VSX Scalar Subtract Quad-Precision */ + case 548: /* VSX Scalar Divide Quad-Precision */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ + case 100: /* VSX Scalar Copy Sign Quad-Precision */ + case 868: /* VSX Scalar Insert Exponent Quad-Precision */ + ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32); + return 0; + + case 804: + switch (PPC_FIELD (insn, 11, 5)) + { + case 27: /* VSX Scalar Square Root Quad-Precision */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + /* FALL-THROUGH */ + case 0: /* VSX Scalar Absolute Quad-Precision */ + case 2: /* VSX Scalar Extract Exponent Quad-Precision */ + case 8: /* VSX Scalar Negative Absolute Quad-Precision */ + case 16: /* VSX Scalar Negate Quad-Precision */ + case 18: /* VSX Scalar Extract Significand Quad-Precision */ + ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32); + return 0; + } + break; + + case 836: + switch (PPC_FIELD (insn, 11, 5)) + { + case 1: /* VSX Scalar truncate & Convert Quad-Precision format + to Unsigned Word format */ + case 2: /* VSX Scalar Convert Unsigned Doubleword format to + Quad-Precision format */ + case 9: /* VSX Scalar truncate & Convert Quad-Precision format + to Signed Word format */ + case 10: /* VSX Scalar Convert Signed Doubleword format to + Quad-Precision format */ + case 17: /* VSX Scalar truncate & Convert Quad-Precision format + to Unsigned Doubleword format */ + case 20: /* VSX Scalar round & Convert Quad-Precision format to + Double-Precision format */ + case 22: /* VSX Scalar Convert Double-Precision format to + Quad-Precision format */ + case 25: /* VSX Scalar truncate & Convert Quad-Precision format + to Signed Doubleword format */ + record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum); + ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32); + return 0; + } } fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x " - "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext); + "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext); return -1; } @@ -5312,12 +5844,21 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, } break; - case 57: /* Load Floating-Point Double Pair */ - if (PPC_FIELD (insn, 30, 2) != 0) - goto UNKNOWN_OP; - tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1); - record_full_arch_list_add_reg (regcache, tmp); - record_full_arch_list_add_reg (regcache, tmp + 1); + case 57: + switch (insn & 0x3) + { + case 0: /* Load Floating-Point Double Pair */ + tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1); + record_full_arch_list_add_reg (regcache, tmp); + record_full_arch_list_add_reg (regcache, tmp + 1); + break; + case 2: /* Load VSX Scalar Doubleword */ + case 3: /* Load VSX Scalar Single */ + ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32); + break; + default: + goto UNKNOWN_OP; + } break; case 58: /* Load Doubleword */ @@ -5343,7 +5884,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, return -1; break; - case 61: /* Store Floating-Point Double Pair */ + case 61: + if (ppc_process_record_op61 (gdbarch, regcache, addr, insn) != 0) + return -1; + break; + case 62: /* Store Doubleword */ /* Store Doubleword with Update */ /* Store Quadword with Update */ @@ -5352,7 +5897,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, int size; int sub2 = PPC_FIELD (insn, 30, 2); - if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2)) + if (sub2 > 2) goto UNKNOWN_OP; if (PPC_RA (insn) != 0) @@ -5360,7 +5905,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, tdep->ppc_gp0_regnum + PPC_RA (insn), &addr); - size = ((op6 == 61) || sub2 == 2) ? 16 : 8; + size = (sub2 == 2) ? 16 : 8; addr += PPC_DS (insn) << 2; record_full_arch_list_add_mem (addr, size); @@ -5872,7 +6417,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); - set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1); set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum); set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno); @@ -5897,8 +6441,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write); + set_gdbarch_ax_pseudo_register_collect (gdbarch, + rs6000_ax_pseudo_register_collect); } + set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address); + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); /* Select instruction printer. */ @@ -5951,7 +6499,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + + set_gdbarch_breakpoint_kind_from_pc (gdbarch, + rs6000_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, + rs6000_breakpoint::bp_from_kind); /* The value of symbols of type N_SO and N_FUN maybe null when it shouldn't be. */ @@ -5999,8 +6551,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) switch (info.osabi) { case GDB_OSABI_LINUX: - case GDB_OSABI_NETBSD_AOUT: - case GDB_OSABI_NETBSD_ELF: + case GDB_OSABI_NETBSD: case GDB_OSABI_UNKNOWN: set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind); @@ -6062,6 +6613,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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; }