summaryrefslogtreecommitdiff
path: root/gdb/rs6000-tdep.c
diff options
context:
space:
mode:
authorandreast <andreast>2013-02-01 20:54:17 +0000
committerandreast <andreast>2013-02-01 20:54:17 +0000
commit6f6a03520777c2efba7bbe5f4a5788cdbe5e8ed2 (patch)
tree0d9c6471f8c526976ee7b29d206d8fad3aa1785c /gdb/rs6000-tdep.c
parentc4dda951d0538c86dd56526ddaf1819f8a012681 (diff)
downloadgdb-6f6a03520777c2efba7bbe5f4a5788cdbe5e8ed2.tar.gz
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 a15f757072d..5bc11055dca 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 */