aboutsummaryrefslogtreecommitdiff
path: root/gdb/rs6000-tdep.c
diff options
context:
space:
mode:
authorAndreas Tobler <andreast@sourceware.org>2013-02-01 20:54:18 +0000
committerAndreas Tobler <andreast@sourceware.org>2013-02-01 20:54:18 +0000
commitd78489bf604bd655936b653e8aacaef50885a692 (patch)
treee70a81185ff07f72f15cca46532b129b26ef003e /gdb/rs6000-tdep.c
parent8db60374ebbe2b436929e27ce80b2dddb2c4eb13 (diff)
downloadgdb-d78489bf604bd655936b653e8aacaef50885a692.zip
gdb-d78489bf604bd655936b653e8aacaef50885a692.tar.gz
gdb-d78489bf604bd655936b653e8aacaef50885a692.tar.bz2
2013-02-01 Andreas Tobler <andreast@fgznet.ch>
* Makefile.in (ALL_TARGET_OBS): Add ppc64-tdep.o. (HFILES_NO_SRCDIR): Add ppc64-tdep.h. (ALLDEPFILES): Add ppc64-tdep.c. * configure.tgt (powerpc-*-linux* | powerpc64-*-linux*): Add ppc64-tdep.o to gdb_target_obs. * ppc64-tdep.h: New file. * ppc64-tdep.c: New file. (insn_d, insn_ds, insn_xfx, ppc64_desc_entry_point): Move from ppc-linux-tdep.c to here. (PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN) (PPC64_STANDARD_LINKAGE2_LEN): Likewise and use ARRAY_SIZE macro. (ppc64_standard_linkage1_target, ppc64_standard_linkage2_target) (ppc64_standard_linkage3_target, ppc64_skip_trampoline_code): Move from ppc-linux-tdep.c to here. (ppc64_convert_from_func_ptr_addr): Rename from ppc64_linux_convert_from_func_ptr_addr to ppc64_convert_from_func_ptr_addr and move from ppc-linux-tdep.c to here. * rs6000-tdep.c: (read_insn): Move from ppc-linux-tdep.c to here. (insns_match_pattern, insn_d_field, insn_ds_field): Move from ppc-linux-tdep.c to here and rename them with the ppc_ prefix. * ppc-linux-tdep.c: Include ppc64-tdep.h. Removed above functions. (ppc_linux_init_abi): Adjust.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r--gdb/rs6000-tdep.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index a15f757..5bc1105 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4238,6 +4238,68 @@ show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value);
}
+/* Read a PPC instruction from memory. PPC instructions are always
+ big-endian, no matter what endianness the program is running in, so
+ we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer. */
+
+static unsigned int
+read_insn (CORE_ADDR pc)
+{
+ return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG);
+}
+
+/* Return non-zero if the instructions at PC match the series
+ described in PATTERN, or zero otherwise. PATTERN is an array of
+ 'struct ppc_insn_pattern' objects, terminated by an entry whose
+ mask is zero.
+
+ When the match is successful, fill INSN[i] with what PATTERN[i]
+ matched. If PATTERN[i] is optional, and the instruction wasn't
+ present, set INSN[i] to 0 (which is not a valid PPC instruction).
+ INSN should have as many elements as PATTERN. Note that, if
+ PATTERN contains optional instructions which aren't present in
+ memory, then INSN will have holes, so INSN[i] isn't necessarily the
+ i'th instruction in memory. */
+
+int
+ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern,
+ unsigned int *insn)
+{
+ int i;
+
+ for (i = 0; pattern[i].mask; i++)
+ {
+ insn[i] = read_insn (pc);
+ if ((insn[i] & pattern[i].mask) == pattern[i].data)
+ pc += 4;
+ else if (pattern[i].optional)
+ insn[i] = 0;
+ else
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Return the 'd' field of the d-form instruction INSN, properly
+ sign-extended. */
+
+CORE_ADDR
+ppc_insn_d_field (unsigned int insn)
+{
+ return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000);
+}
+
+/* Return the 'ds' field of the ds-form instruction INSN, with the two
+ zero bits concatenated at the right, and properly
+ sign-extended. */
+
+CORE_ADDR
+ppc_insn_ds_field (unsigned int insn)
+{
+ return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000);
+}
+
/* Initialization code. */
/* -Wmissing-prototypes */