This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Move instruction decoding into new arch/ directory


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=787749ead66eee8c20754c160bd79404b2109553

commit 787749ead66eee8c20754c160bd79404b2109553
Author: Pierre Langlois <pierre.langlois@arm.com>
Date:   Mon Sep 21 15:01:04 2015 +0100

    Move instruction decoding into new arch/ directory
    
    This patch moves the following functions into the arch/ common
    directory, in new files arch/aarch64-insn.{h,c}.  They are prefixed with
    'aarch64_':
    
     - aarch64_decode_adrp
     - aarch64_decode_b
     - aarch64_decode_cb
     - aarch64_decode_tb
    
    We will need them to implement fast tracepoints in GDBserver.
    
    For consistency, this patch also adds the 'aarch64_' prefix to static
    decoding functions that do not need to be shared right now.
    
    V2:
     make sure the formatting issues propagated
     fix `gdbserver/configure.srv'.
    
    gdb/ChangeLog:
    
    	* Makefile.in (ALL_64_TARGET_OBS): Add aarch64-insn.o.
    	(HFILES_NO_SRCDIR): Add arch/aarch64-insn.h.
    	(aarch64-insn.o): New rule.
    	* configure.tgt (aarch64*-*-elf): Add aarch64-insn.o.
    	(aarch64*-*-linux*): Likewise.
    	* arch/aarch64-insn.c: New file.
    	* arch/aarch64-insn.h: New file.
    	* aarch64-tdep.c: Include arch/aarch64-insn.h.
    	(aarch64_debug): Move to arch/aarch64-insn.c.  Declare in
    	arch/aarch64-insn.h.
    	(decode_add_sub_imm): Rename to ...
    	(aarch64_decode_add_sub_imm): ... this.
    	(decode_adrp): Rename to ...
    	(aarch64_decode_adrp): ... this.  Move to arch/aarch64-insn.c.
    	Declare in arch/aarch64-insn.h.
    	(decode_b): Rename to ...
    	(aarch64_decode_b): ... this.  Move to arch/aarch64-insn.c.
    	Declare in arch/aarch64-insn.h.
    	(decode_bcond): Rename to ...
    	(aarch64_decode_bcond): ... this.  Move to arch/aarch64-insn.c.
    	Declare in arch/aarch64-insn.h.
    	(decode_br): Rename to ...
    	(aarch64_decode_br): ... this.
    	(decode_cb): Rename to ...
    	(aarch64_decode_cb): ... this.  Move to arch/aarch64-insn.c.
    	Declare in arch/aarch64-insn.h.
    	(decode_eret): Rename to ...
    	(aarch64_decode_eret): ... this.
    	(decode_movz): Rename to ...
    	(aarch64_decode_movz): ... this.
    	(decode_orr_shifted_register_x): Rename to ...
    	(aarch64_decode_orr_shifted_register_x): ... this.
    	(decode_ret): Rename to ...
    	(aarch64_decode_ret): ... this.
    	(decode_stp_offset): Rename to ...
    	(aarch64_decode_stp_offset): ... this.
    	(decode_stp_offset_wb): Rename to ...
    	(aarch64_decode_stp_offset_wb): ... this.
    	(decode_stur): Rename to ...
    	(aarch64_decode_stur): ... this.
    	(decode_tb): Rename to ...
    	(aarch64_decode_tb): ... this.  Move to arch/aarch64-insn.c.
    	Declare in arch/aarch64-insn.h.
    	(aarch64_analyze_prologue): Adjust calls to renamed functions.
    
    gdb/gdbserver/ChangeLog:
    
    	* Makefile.in (aarch64-insn.o): New rule.
    	* configure.srv (aarch64*-*-linux*): Add aarch64-insn.o.

Diff:
---
 gdb/ChangeLog               |  47 +++++++++
 gdb/Makefile.in             |  13 ++-
 gdb/aarch64-tdep.c          | 235 +++++++-------------------------------------
 gdb/arch/aarch64-insn.c     | 218 ++++++++++++++++++++++++++++++++++++++++
 gdb/arch/aarch64-insn.h     |  38 +++++++
 gdb/configure.tgt           |   4 +-
 gdb/gdbserver/ChangeLog     |   5 +
 gdb/gdbserver/Makefile.in   |   6 ++
 gdb/gdbserver/configure.srv |   1 +
 9 files changed, 366 insertions(+), 201 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fe56b75..7d8feeb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,50 @@
+2015-09-21  Pierre Langlois  <pierre.langlois@arm.com>
+
+	* Makefile.in (ALL_64_TARGET_OBS): Add aarch64-insn.o.
+	(HFILES_NO_SRCDIR): Add arch/aarch64-insn.h.
+	(aarch64-insn.o): New rule.
+	* configure.tgt (aarch64*-*-elf): Add aarch64-insn.o.
+	(aarch64*-*-linux*): Likewise.
+	* arch/aarch64-insn.c: New file.
+	* arch/aarch64-insn.h: New file.
+	* aarch64-tdep.c: Include arch/aarch64-insn.h.
+	(aarch64_debug): Move to arch/aarch64-insn.c.  Declare in
+	arch/aarch64-insn.h.
+	(decode_add_sub_imm): Rename to ...
+	(aarch64_decode_add_sub_imm): ... this.
+	(decode_adrp): Rename to ...
+	(aarch64_decode_adrp): ... this.  Move to arch/aarch64-insn.c.
+	Declare in arch/aarch64-insn.h.
+	(decode_b): Rename to ...
+	(aarch64_decode_b): ... this.  Move to arch/aarch64-insn.c.
+	Declare in arch/aarch64-insn.h.
+	(decode_bcond): Rename to ...
+	(aarch64_decode_bcond): ... this.  Move to arch/aarch64-insn.c.
+	Declare in arch/aarch64-insn.h.
+	(decode_br): Rename to ...
+	(aarch64_decode_br): ... this.
+	(decode_cb): Rename to ...
+	(aarch64_decode_cb): ... this.  Move to arch/aarch64-insn.c.
+	Declare in arch/aarch64-insn.h.
+	(decode_eret): Rename to ...
+	(aarch64_decode_eret): ... this.
+	(decode_movz): Rename to ...
+	(aarch64_decode_movz): ... this.
+	(decode_orr_shifted_register_x): Rename to ...
+	(aarch64_decode_orr_shifted_register_x): ... this.
+	(decode_ret): Rename to ...
+	(aarch64_decode_ret): ... this.
+	(decode_stp_offset): Rename to ...
+	(aarch64_decode_stp_offset): ... this.
+	(decode_stp_offset_wb): Rename to ...
+	(aarch64_decode_stp_offset_wb): ... this.
+	(decode_stur): Rename to ...
+	(aarch64_decode_stur): ... this.
+	(decode_tb): Rename to ...
+	(aarch64_decode_tb): ... this.  Move to arch/aarch64-insn.c.
+	Declare in arch/aarch64-insn.h.
+	(aarch64_analyze_prologue): Adjust calls to renamed functions.
+
 2015-09-20  Doug Evans  <xdje42@gmail.com>
 
 	* dwarf2read.c (add_partial_symbol): Remove outdated comments.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 5659116..d5ca2ee 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -644,7 +644,7 @@ TARGET_OBS = @TARGET_OBS@
 # All target-dependent objects files that require 64-bit CORE_ADDR
 # (used with --enable-targets=all --enable-64-bit-bfd).
 ALL_64_TARGET_OBS = \
-	aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o \
+	aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o aarch64-insn.o \
 	alphabsd-tdep.o alphafbsd-tdep.o alpha-linux-tdep.o alpha-mdebug-tdep.o \
 	alphanbsd-tdep.o alphaobsd-tdep.o alpha-tdep.o \
 	amd64fbsd-tdep.o amd64-darwin-tdep.o amd64-dicos-tdep.o \
@@ -986,7 +986,7 @@ common/common-debug.h common/cleanups.h common/gdb_setjmp.h \
 common/common-exceptions.h target/target.h common/symbol.h \
 common/common-regcache.h fbsd-tdep.h nat/linux-personality.h \
 common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h \
-nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h
+nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -2336,6 +2336,15 @@ aarch64-linux.o: ${srcdir}/nat/aarch64-linux.c
 	$(COMPILE) $(srcdir)/nat/aarch64-linux.c
 	$(POSTCOMPILE)
 
+# gdb/arch/ dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the sub-directory.
+
+aarch64-insn.o: ${srcdir}/arch/aarch64-insn.c
+	$(COMPILE) $(srcdir)/arch/aarch64-insn.c
+	$(POSTCOMPILE)
+
 #
 # gdb/tui/ dependencies
 #
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 9a4eda2..92e2404 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -57,6 +57,8 @@
 
 #include "features/aarch64.c"
 
+#include "arch/aarch64-insn.h"
+
 /* Pseudo register base numbers.  */
 #define AARCH64_Q0_REGNUM 0
 #define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + 32)
@@ -179,9 +181,6 @@ struct aarch64_prologue_cache
   struct trad_frame_saved_reg *saved_regs;
 };
 
-/* Toggle this file's internal debugging dump.  */
-static int aarch64_debug;
-
 static void
 show_aarch64_debug (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
@@ -231,8 +230,8 @@ decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
 
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 static int
-decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd, unsigned *rn,
-		    int32_t *imm)
+aarch64_decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd,
+			    unsigned *rn, int32_t *imm)
 {
   if ((insn & 0x9f000000) == 0x91000000)
     {
@@ -271,94 +270,6 @@ decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd, unsigned *rn,
   return 0;
 }
 
-/* Decode an opcode if it represents an ADRP instruction.
-
-   ADDR specifies the address of the opcode.
-   INSN specifies the opcode to test.
-   RD receives the 'rd' field from the decoded instruction.
-
-   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
-
-static int
-decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
-{
-  if (decode_masked_match (insn, 0x9f000000, 0x90000000))
-    {
-      *rd = (insn >> 0) & 0x1f;
-
-      if (aarch64_debug)
-	{
-	  debug_printf ("decode: 0x%s 0x%x adrp x%u, #?\n",
-			core_addr_to_string_nz (addr), insn, *rd);
-	}
-      return 1;
-    }
-  return 0;
-}
-
-/* Decode an opcode if it represents an branch immediate or branch
-   and link immediate instruction.
-
-   ADDR specifies the address of the opcode.
-   INSN specifies the opcode to test.
-   IS_BL receives the 'op' bit from the decoded instruction.
-   OFFSET receives the immediate offset from the decoded instruction.
-
-   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
-
-static int
-decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl, int32_t *offset)
-{
-  /* b  0001 01ii iiii iiii iiii iiii iiii iiii */
-  /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
-  if (decode_masked_match (insn, 0x7c000000, 0x14000000))
-    {
-      *is_bl = (insn >> 31) & 0x1;
-      *offset = extract_signed_bitfield (insn, 26, 0) << 2;
-
-      if (aarch64_debug)
-	{
-	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
-			core_addr_to_string_nz (addr), insn,
-			*is_bl ? "bl" : "b",
-			core_addr_to_string_nz (addr + *offset));
-	}
-
-      return 1;
-    }
-  return 0;
-}
-
-/* Decode an opcode if it represents a conditional branch instruction.
-
-   ADDR specifies the address of the opcode.
-   INSN specifies the opcode to test.
-   COND receives the branch condition field from the decoded
-   instruction.
-   OFFSET receives the immediate offset from the decoded instruction.
-
-   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
-
-static int
-decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond, int32_t *offset)
-{
-  /* b.cond  0101 0100 iiii iiii iiii iiii iii0 cccc */
-  if (decode_masked_match (insn, 0xff000010, 0x54000000))
-    {
-      *cond = (insn >> 0) & 0xf;
-      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
-
-      if (aarch64_debug)
-	{
-	  debug_printf ("decode: 0x%s 0x%x b<%u> 0x%s\n",
-			core_addr_to_string_nz (addr), insn, *cond,
-			core_addr_to_string_nz (addr + *offset));
-	}
-      return 1;
-    }
-  return 0;
-}
-
 /* Decode an opcode if it represents a branch via register instruction.
 
    ADDR specifies the address of the opcode.
@@ -369,7 +280,8 @@ decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond, int32_t *offset)
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr, unsigned *rn)
+aarch64_decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr,
+		   unsigned *rn)
 {
   /*         8   4   0   6   2   8   4   0 */
   /* blr  110101100011111100000000000rrrrr */
@@ -391,42 +303,6 @@ decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr, unsigned *rn)
   return 0;
 }
 
-/* Decode an opcode if it represents a CBZ or CBNZ instruction.
-
-   ADDR specifies the address of the opcode.
-   INSN specifies the opcode to test.
-   IS64 receives the 'sf' field from the decoded instruction.
-   IS_CBNZ receives the 'op' field from the decoded instruction.
-   RN receives the 'rn' field from the decoded instruction.
-   OFFSET receives the 'imm19' field from the decoded instruction.
-
-   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
-
-static int
-decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
-	   unsigned *rn, int32_t *offset)
-{
-  /* cbz  T011 010o iiii iiii iiii iiii iiir rrrr */
-  /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
-  if (decode_masked_match (insn, 0x7e000000, 0x34000000))
-    {
-      *rn = (insn >> 0) & 0x1f;
-      *is64 = (insn >> 31) & 0x1;
-      *is_cbnz = (insn >> 24) & 0x1;
-      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
-
-      if (aarch64_debug)
-	{
-	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
-			core_addr_to_string_nz (addr), insn,
-			*is_cbnz ? "cbnz" : "cbz",
-			core_addr_to_string_nz (addr + *offset));
-	}
-      return 1;
-    }
-  return 0;
-}
-
 /* Decode an opcode if it represents a ERET instruction.
 
    ADDR specifies the address of the opcode.
@@ -435,7 +311,7 @@ decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_eret (CORE_ADDR addr, uint32_t insn)
+aarch64_decode_eret (CORE_ADDR addr, uint32_t insn)
 {
   /* eret 1101 0110 1001 1111 0000 0011 1110 0000 */
   if (insn == 0xd69f03e0)
@@ -459,7 +335,7 @@ decode_eret (CORE_ADDR addr, uint32_t insn)
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
+aarch64_decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
 {
   if (decode_masked_match (insn, 0xff800000, 0x52800000))
     {
@@ -488,9 +364,9 @@ decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_orr_shifted_register_x (CORE_ADDR addr,
-			       uint32_t insn, unsigned *rd, unsigned *rn,
-			       unsigned *rm, int32_t *imm)
+aarch64_decode_orr_shifted_register_x (CORE_ADDR addr, uint32_t insn,
+				       unsigned *rd, unsigned *rn,
+				       unsigned *rm, int32_t *imm)
 {
   if (decode_masked_match (insn, 0xff200000, 0xaa000000))
     {
@@ -519,7 +395,7 @@ decode_orr_shifted_register_x (CORE_ADDR addr,
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
+aarch64_decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
 {
   if (decode_masked_match (insn, 0xfffffc1f, 0xd65f0000))
     {
@@ -547,9 +423,8 @@ decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_stp_offset (CORE_ADDR addr,
-		   uint32_t insn,
-		   unsigned *rt1, unsigned *rt2, unsigned *rn, int32_t *imm)
+aarch64_decode_stp_offset (CORE_ADDR addr, uint32_t insn, unsigned *rt1,
+			   unsigned *rt2, unsigned *rn, int32_t *imm)
 {
   if (decode_masked_match (insn, 0xffc00000, 0xa9000000))
     {
@@ -583,10 +458,8 @@ decode_stp_offset (CORE_ADDR addr,
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_stp_offset_wb (CORE_ADDR addr,
-		      uint32_t insn,
-		      unsigned *rt1, unsigned *rt2, unsigned *rn,
-		      int32_t *imm)
+aarch64_decode_stp_offset_wb (CORE_ADDR addr, uint32_t insn, unsigned *rt1,
+			      unsigned *rt2, unsigned *rn, int32_t *imm)
 {
   if (decode_masked_match (insn, 0xffc00000, 0xa9800000))
     {
@@ -620,8 +493,8 @@ decode_stp_offset_wb (CORE_ADDR addr,
    Return 1 if the opcodes matches and is decoded, otherwise 0.  */
 
 static int
-decode_stur (CORE_ADDR addr, uint32_t insn, int *is64, unsigned *rt,
-	     unsigned *rn, int32_t *imm)
+aarch64_decode_stur (CORE_ADDR addr, uint32_t insn, int *is64,
+		     unsigned *rt, unsigned *rn, int32_t *imm)
 {
   if (decode_masked_match (insn, 0xbfe00c00, 0xb8000000))
     {
@@ -641,42 +514,6 @@ decode_stur (CORE_ADDR addr, uint32_t insn, int *is64, unsigned *rt,
   return 0;
 }
 
-/* Decode an opcode if it represents a TBZ or TBNZ instruction.
-
-   ADDR specifies the address of the opcode.
-   INSN specifies the opcode to test.
-   IS_TBNZ receives the 'op' field from the decoded instruction.
-   BIT receives the bit position field from the decoded instruction.
-   RT receives 'rt' field from the decoded instruction.
-   IMM receives 'imm' field from the decoded instruction.
-
-   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
-
-static int
-decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz, unsigned *bit,
-	   unsigned *rt, int32_t *imm)
-{
-  /* tbz  b011 0110 bbbb biii iiii iiii iiir rrrr */
-  /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
-  if (decode_masked_match (insn, 0x7e000000, 0x36000000))
-    {
-      *rt = (insn >> 0) & 0x1f;
-      *is_tbnz = (insn >> 24) & 0x1;
-      *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
-      *imm = extract_signed_bitfield (insn, 14, 5) << 2;
-
-      if (aarch64_debug)
-	{
-	  debug_printf ("decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
-			core_addr_to_string_nz (addr), insn,
-			*is_tbnz ? "tbnz" : "tbz", *rt, *bit,
-			core_addr_to_string_nz (addr + *imm));
-	}
-      return 1;
-    }
-  return 0;
-}
-
 /* Analyze a prologue, looking for a recognizable stack frame
    and frame pointer.  Scan until we encounter a store that could
    clobber the stack frame unexpectedly, or an unknown instruction.  */
@@ -718,39 +555,40 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
 
       insn = read_memory_unsigned_integer (start, 4, byte_order_for_code);
 
-      if (decode_add_sub_imm (start, insn, &rd, &rn, &imm))
+      if (aarch64_decode_add_sub_imm (start, insn, &rd, &rn, &imm))
 	regs[rd] = pv_add_constant (regs[rn], imm);
-      else if (decode_adrp (start, insn, &rd))
+      else if (aarch64_decode_adrp (start, insn, &rd))
 	regs[rd] = pv_unknown ();
-      else if (decode_b (start, insn, &is_link, &offset))
+      else if (aarch64_decode_b (start, insn, &is_link, &offset))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_bcond (start, insn, &cond, &offset))
+      else if (aarch64_decode_bcond (start, insn, &cond, &offset))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_br (start, insn, &is_link, &rn))
+      else if (aarch64_decode_br (start, insn, &is_link, &rn))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_cb (start, insn, &is64, &is_cbnz, &rn, &offset))
+      else if (aarch64_decode_cb (start, insn, &is64, &is_cbnz, &rn,
+				  &offset))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_eret (start, insn))
+      else if (aarch64_decode_eret (start, insn))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_movz (start, insn, &rd))
+      else if (aarch64_decode_movz (start, insn, &rd))
 	regs[rd] = pv_unknown ();
-      else
-	if (decode_orr_shifted_register_x (start, insn, &rd, &rn, &rm, &imm))
+      else if (aarch64_decode_orr_shifted_register_x (start, insn, &rd,
+						      &rn, &rm, &imm))
 	{
 	  if (imm == 0 && rn == 31)
 	    regs[rd] = regs[rm];
@@ -765,17 +603,18 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
 	      break;
 	    }
 	}
-      else if (decode_ret (start, insn, &rn))
+      else if (aarch64_decode_ret (start, insn, &rn))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
 	}
-      else if (decode_stur (start, insn, &is64, &rt, &rn, &offset))
+      else if (aarch64_decode_stur (start, insn, &is64, &rt, &rn, &offset))
 	{
 	  pv_area_store (stack, pv_add_constant (regs[rn], offset),
 			 is64 ? 8 : 4, regs[rt]);
 	}
-      else if (decode_stp_offset (start, insn, &rt1, &rt2, &rn, &imm))
+      else if (aarch64_decode_stp_offset (start, insn, &rt1, &rt2, &rn,
+					  &imm))
 	{
 	  /* If recording this store would invalidate the store area
 	     (perhaps because rn is not known) then we should abandon
@@ -793,7 +632,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
 	  pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
 			 regs[rt2]);
 	}
-      else if (decode_stp_offset_wb (start, insn, &rt1, &rt2, &rn, &imm))
+      else if (aarch64_decode_stp_offset_wb (start, insn, &rt1, &rt2, &rn,
+					     &imm))
 	{
 	  /* If recording this store would invalidate the store area
 	     (perhaps because rn is not known) then we should abandon
@@ -812,7 +652,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
 			 regs[rt2]);
 	  regs[rn] = pv_add_constant (regs[rn], imm);
 	}
-      else if (decode_tb (start, insn, &is_tbnz, &bit, &rn, &offset))
+      else if (aarch64_decode_tb (start, insn, &is_tbnz, &bit, &rn,
+				  &offset))
 	{
 	  /* Stop analysis on branch.  */
 	  break;
@@ -2663,7 +2504,7 @@ aarch64_software_single_step (struct frame_info *frame)
 					   byte_order_for_code);
 
       /* Check if the instruction is a conditional branch.  */
-      if (decode_bcond (loc, insn, &cond, &offset))
+      if (aarch64_decode_bcond (loc, insn, &cond, &offset))
 	{
 	  if (bc_insn_count >= 1)
 	    return 0;
diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c
new file mode 100644
index 0000000..3a289a2
--- /dev/null
+++ b/gdb/arch/aarch64-insn.c
@@ -0,0 +1,218 @@
+/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "common-defs.h"
+#include "aarch64-insn.h"
+
+/* Toggle this file's internal debugging dump.  */
+int aarch64_debug = 0;
+
+/* Extract a signed value from a bit field within an instruction
+   encoding.
+
+   INSN is the instruction opcode.
+
+   WIDTH specifies the width of the bit field to extract (in bits).
+
+   OFFSET specifies the least significant bit of the field where bits
+   are numbered zero counting from least to most significant.  */
+
+static int32_t
+extract_signed_bitfield (uint32_t insn, unsigned width, unsigned offset)
+{
+  unsigned shift_l = sizeof (int32_t) * 8 - (offset + width);
+  unsigned shift_r = sizeof (int32_t) * 8 - width;
+
+  return ((int32_t) insn << shift_l) >> shift_r;
+}
+
+/* Determine if specified bits within an instruction opcode matches a
+   specific pattern.
+
+   INSN is the instruction opcode.
+
+   MASK specifies the bits within the opcode that are to be tested
+   agsinst for a match with PATTERN.  */
+
+static int
+decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
+{
+  return (insn & mask) == pattern;
+}
+
+/* Decode an opcode if it represents an ADRP instruction.
+
+   ADDR specifies the address of the opcode.
+   INSN specifies the opcode to test.
+   RD receives the 'rd' field from the decoded instruction.
+
+   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
+
+int
+aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
+{
+  if (decode_masked_match (insn, 0x9f000000, 0x90000000))
+    {
+      *rd = (insn >> 0) & 0x1f;
+
+      if (aarch64_debug)
+	{
+	  debug_printf ("decode: 0x%s 0x%x adrp x%u, #?\n",
+			core_addr_to_string_nz (addr), insn, *rd);
+	}
+      return 1;
+    }
+  return 0;
+}
+
+/* Decode an opcode if it represents an branch immediate or branch
+   and link immediate instruction.
+
+   ADDR specifies the address of the opcode.
+   INSN specifies the opcode to test.
+   IS_BL receives the 'op' bit from the decoded instruction.
+   OFFSET receives the immediate offset from the decoded instruction.
+
+   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
+
+int
+aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
+		  int32_t *offset)
+{
+  /* b  0001 01ii iiii iiii iiii iiii iiii iiii */
+  /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
+  if (decode_masked_match (insn, 0x7c000000, 0x14000000))
+    {
+      *is_bl = (insn >> 31) & 0x1;
+      *offset = extract_signed_bitfield (insn, 26, 0) << 2;
+
+      if (aarch64_debug)
+	{
+	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
+			core_addr_to_string_nz (addr), insn,
+			*is_bl ? "bl" : "b",
+			core_addr_to_string_nz (addr + *offset));
+	}
+
+      return 1;
+    }
+  return 0;
+}
+
+/* Decode an opcode if it represents a conditional branch instruction.
+
+   ADDR specifies the address of the opcode.
+   INSN specifies the opcode to test.
+   COND receives the branch condition field from the decoded
+   instruction.
+   OFFSET receives the immediate offset from the decoded instruction.
+
+   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
+
+int
+aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
+		      int32_t *offset)
+{
+  /* b.cond  0101 0100 iiii iiii iiii iiii iii0 cccc */
+  if (decode_masked_match (insn, 0xff000010, 0x54000000))
+    {
+      *cond = (insn >> 0) & 0xf;
+      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+
+      if (aarch64_debug)
+	{
+	  debug_printf ("decode: 0x%s 0x%x b<%u> 0x%s\n",
+			core_addr_to_string_nz (addr), insn, *cond,
+			core_addr_to_string_nz (addr + *offset));
+	}
+      return 1;
+    }
+  return 0;
+}
+
+/* Decode an opcode if it represents a CBZ or CBNZ instruction.
+
+   ADDR specifies the address of the opcode.
+   INSN specifies the opcode to test.
+   IS64 receives the 'sf' field from the decoded instruction.
+   IS_CBNZ receives the 'op' field from the decoded instruction.
+   RN receives the 'rn' field from the decoded instruction.
+   OFFSET receives the 'imm19' field from the decoded instruction.
+
+   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
+
+int
+aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
+		   unsigned *rn, int32_t *offset)
+{
+  /* cbz  T011 010o iiii iiii iiii iiii iiir rrrr */
+  /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
+  if (decode_masked_match (insn, 0x7e000000, 0x34000000))
+    {
+      *rn = (insn >> 0) & 0x1f;
+      *is64 = (insn >> 31) & 0x1;
+      *is_cbnz = (insn >> 24) & 0x1;
+      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+
+      if (aarch64_debug)
+	{
+	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
+			core_addr_to_string_nz (addr), insn,
+			*is_cbnz ? "cbnz" : "cbz",
+			core_addr_to_string_nz (addr + *offset));
+	}
+      return 1;
+    }
+  return 0;
+}
+
+/* Decode an opcode if it represents a TBZ or TBNZ instruction.
+
+   ADDR specifies the address of the opcode.
+   INSN specifies the opcode to test.
+   IS_TBNZ receives the 'op' field from the decoded instruction.
+   BIT receives the bit position field from the decoded instruction.
+   RT receives 'rt' field from the decoded instruction.
+   IMM receives 'imm' field from the decoded instruction.
+
+   Return 1 if the opcodes matches and is decoded, otherwise 0.  */
+
+int
+aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
+		   unsigned *bit, unsigned *rt, int32_t *imm)
+{
+  /* tbz  b011 0110 bbbb biii iiii iiii iiir rrrr */
+  /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
+  if (decode_masked_match (insn, 0x7e000000, 0x36000000))
+    {
+      *rt = (insn >> 0) & 0x1f;
+      *is_tbnz = (insn >> 24) & 0x1;
+      *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
+      *imm = extract_signed_bitfield (insn, 14, 5) << 2;
+
+      if (aarch64_debug)
+	{
+	  debug_printf ("decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
+			core_addr_to_string_nz (addr), insn,
+			*is_tbnz ? "tbnz" : "tbz", *rt, *bit,
+			core_addr_to_string_nz (addr + *imm));
+	}
+      return 1;
+    }
+  return 0;
+}
diff --git a/gdb/arch/aarch64-insn.h b/gdb/arch/aarch64-insn.h
new file mode 100644
index 0000000..7775a34
--- /dev/null
+++ b/gdb/arch/aarch64-insn.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef AARCH64_INSN_H
+#define AARCH64_INSN_H 1
+
+extern int aarch64_debug;
+
+int aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd);
+
+int aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
+		      int32_t *offset);
+
+int aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
+			  int32_t *offset);
+
+int aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64,
+		       int *is_cbnz, unsigned *rn, int32_t *offset);
+
+int aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
+		       unsigned *bit, unsigned *rt, int32_t *imm);
+
+#endif
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index c42b4df..33d4cfc 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -38,12 +38,12 @@ esac
 case "${targ}" in
 aarch64*-*-elf)
 	# Target: AArch64 embedded system
-	gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o"
+	gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o aarch64-insn.o"
 	;;
 
 aarch64*-*-linux*)
 	# Target: AArch64 linux
-	gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o \
+	gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o aarch64-insn.o \
 			arm-tdep.o arm-linux-tdep.o \
 			glibc-tdep.o linux-tdep.o solib-svr4.o \
 			symfile-mem.o linux-record.o"
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 16b02ca..83a7848 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-21  Pierre Langlois  <pierre.langlois@arm.com>
+
+	* Makefile.in (aarch64-insn.o): New rule.
+	* configure.srv (aarch64*-*-linux*): Add aarch64-insn.o.
+
 2015-09-21  Yao Qi  <yao.qi@linaro.org>
 
 	* ax.c [!IN_PROCESS_AGENT] (gdb_agent_op_sizes): Define it.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index b715a32..d096663 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -625,6 +625,12 @@ linux-namespaces.o: ../nat/linux-namespaces.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Architecture specific object files rules from ../arch
+
+aarch64-insn.o: ../arch/aarch64-insn.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c
 reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index aa232f8..a62df83 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -53,6 +53,7 @@ case "${target}" in
 			srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o"
 			srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
 			srv_tgtobj="$srv_tgtobj aarch64-linux.o"
+			srv_tgtobj="$srv_tgtobj aarch64-insn.o"
 			srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
 			srv_xmlfiles="aarch64.xml"
 			srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]