This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

[PATCH] [ARC] Disassemble correctly extension instructions.


For each MAJOR-MINOR opcode tuple, we can have either a 3-operand, or
2-operand, or a single operand instruction format, depending on the
values present in i-field, and a-field.

The disassembler is reading the section containing the extension
instruction format and stores them in a table.  Each table element
represents a linked list with encodings for a particular MAJOR-MINOR
tuple.

The current implementation checks only against the first element of
the list, hence, the issue.

The current patch is walking the linked list until empty or finds an
opcode match.  It also adds a test outlining the found problem.

Ok to apply?
Claudiu

opcodes/
2016-09-15  Claudiu Zissulescu  <claziss@synopsys.com>

	* arc-dis.c (find_format): Walk the linked list pointed by einsn.

gas/
2016-09-15  Claudiu Zissulescu  <claziss@synopsys.com>

	* testsuite/gas/arc/textinsnxop.d: New file.
	* testsuite/gas/arc/textinsnxop.s: Likewise.
---
 gas/testsuite/gas/arc/textinsnxop.d | 12 ++++++++++++
 gas/testsuite/gas/arc/textinsnxop.s | 10 ++++++++++
 opcodes/arc-dis.c                   |  6 +++---
 3 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 gas/testsuite/gas/arc/textinsnxop.d
 create mode 100644 gas/testsuite/gas/arc/textinsnxop.s

diff --git a/gas/testsuite/gas/arc/textinsnxop.d b/gas/testsuite/gas/arc/textinsnxop.d
new file mode 100644
index 0000000..14556e6
--- /dev/null
+++ b/gas/testsuite/gas/arc/textinsnxop.d
@@ -0,0 +1,12 @@
+#objdump: -d
+
+.*: +file format .*arc.*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <start>:
+   0:	3921 0080           	insn1	r0,r1,r2
+   4:	382f 0061           	insn2	r0,r1
+   8:	392f 407f           	insn3	r1
+   c:	396f 403f           	insn4
diff --git a/gas/testsuite/gas/arc/textinsnxop.s b/gas/testsuite/gas/arc/textinsnxop.s
new file mode 100644
index 0000000..be8111d
--- /dev/null
+++ b/gas/testsuite/gas/arc/textinsnxop.s
@@ -0,0 +1,10 @@
+	.extInstruction insn1, 7, 0x21, SUFFIX_NONE, SYNTAX_3OP
+	.extInstruction insn2, 7, 0x21, SUFFIX_NONE, SYNTAX_2OP
+	.extInstruction insn3, 7, 0x21, SUFFIX_NONE, SYNTAX_1OP
+	.extInstruction insn4, 7, 0x21, SUFFIX_NONE, SYNTAX_NOP
+
+start:
+	insn1	r0,r1,r2
+	insn2	r0,r1
+	insn3	r1
+	insn4
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index d69a01e..9403f91 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -477,15 +477,15 @@ find_format (bfd_vma                       memaddr,
 {
   const struct arc_opcode *opcode = NULL;
   bfd_boolean needs_limm;
-  const extInstruction_t *einsn;
+  const extInstruction_t *einsn, *i;
 
   /* First, try the extension instructions.  */
   einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
-  if (einsn != NULL)
+  for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
     {
       const char *errmsg = NULL;
 
-      opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
+      opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
       if (opcode == NULL)
 	{
 	  (*info->fprintf_func) (info->stream, "\
-- 
1.9.1


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