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] Improve filtering instructions while disassembling.


Hi,

ARC processors may reuse opcodes for different instructions.  This
patch is improving the selection of the instructions when
disassembling.

OK to apply?
Claudiu

gas/
2016-07-14  Claudiu Zissulescu  <claziss@synopsys.com>

	* testsuite/gas/arc/dsp.d: New file.
	* testsuite/gas/arc/dsp.s: Likewise.
	* testsuite/gas/arc/fpu.d: Likewise.
	* testsuite/gas/arc/fpu.s: Likewise.

opcodes/
2016-07-14  Claudiu Zissulescu  <claziss@synopsys.com>

	* arc-dis.c (skipclass): New structure.
	(is_compatible_p): New function.
	(new_element): Likewise.
	(skip_class_p): Likewise.
	(find_format_from_table): Use skip_class_p function.
	(print_insn_arc): Select either ARCEM or ARCHS based on elf
	e_flags.
---
 gas/testsuite/gas/arc/dsp.d |  96 +++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/arc/dsp.s |  90 +++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/arc/fpu.d |  29 ++++++++++++
 gas/testsuite/gas/arc/fpu.s |  24 ++++++++++
 opcodes/arc-dis.c           | 113 +++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 351 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/arc/dsp.d
 create mode 100644 gas/testsuite/gas/arc/dsp.s
 create mode 100644 gas/testsuite/gas/arc/fpu.d
 create mode 100644 gas/testsuite/gas/arc/fpu.s

diff --git a/gas/testsuite/gas/arc/dsp.d b/gas/testsuite/gas/arc/dsp.d
new file mode 100644
index 0000000..09a417e
--- /dev/null
+++ b/gas/testsuite/gas/arc/dsp.d
@@ -0,0 +1,96 @@
+#as: -mcpu=arcem
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arc.*
+
+
+Disassembly of section .text:
+0x[0-9a-f]+ 282f 0084           	abssh	r0,r2
+0x[0-9a-f]+ 282f 003f           	aslacc	r0
+0x[0-9a-f]+ 292f 003f           	aslsacc	r0
+0x[0-9a-f]+ 2a0c 0100           	asrsr	r0,r2,r4
+0x[0-9a-f]+ 321b 8100           	cbflyhf0r	r0,r2,r4
+0x[0-9a-f]+ 302f 00b9           	cbflyhf1r	r0,r2
+0x[0-9a-f]+ 3209 8100           	cmacchfr	r0,r2,r4
+0x[0-9a-f]+ 3208 8100           	cmacchnfr	r0,r2,r4
+0x[0-9a-f]+ 3207 8100           	cmachfr	r0,r2,r4
+0x[0-9a-f]+ 3206 8100           	cmachnfr	r0,r2,r4
+0x[0-9a-f]+ 3205 8100           	cmpychfr	r0,r2,r4
+0x[0-9a-f]+ 3202 8100           	cmpychnfr	r0,r2,r4
+0x[0-9a-f]+ 321b 0100           	cmpyhfmr	r0,r2,r4
+0x[0-9a-f]+ 3201 8100           	cmpyhfr	r0,r2,r4
+0x[0-9a-f]+ 3200 8100           	cmpyhnfr	r0,r2,r4
+0x[0-9a-f]+ 2b2f 003f           	divacc	r0
+0x[0-9a-f]+ 3218 0100           	dmachbl	r0,r2,r4
+0x[0-9a-f]+ 3219 0100           	dmachbm	r0,r2,r4
+0x[0-9a-f]+ 2a2c 0100           	dmachf	r0,r2,r4
+0x[0-9a-f]+ 2a2d 0100           	dmachfr	r0,r2,r4
+0x[0-9a-f]+ 3216 0100           	dmpyhbl	r0,r2,r4
+0x[0-9a-f]+ 3217 0100           	dmpyhbm	r0,r2,r4
+0x[0-9a-f]+ 2a2a 0100           	dmpyhf	r0,r2,r4
+0x[0-9a-f]+ 2a2b 0100           	dmpyhfr	r0,r2,r4
+0x[0-9a-f]+ 2a28 0100           	dmpyhwf	r0,r2,r4
+0x[0-9a-f]+ 2c2f 803f           	flagacc	r0
+0x[0-9a-f]+ 282f 0098           	getacc	r0,r2
+0x[0-9a-f]+ 320c 0100           	macf	r0,r2,r4
+0x[0-9a-f]+ 320d 0100           	macfr	r0,r2,r4
+0x[0-9a-f]+ 3222 0100           	macwhfm	r0,r2,r4
+0x[0-9a-f]+ 3223 0100           	macwhfmr	r0,r2,r4
+0x[0-9a-f]+ 321d 0100           	macwhl	r0,r2,r4
+0x[0-9a-f]+ 321f 0100           	macwhul	r0,r2,r4
+0x[0-9a-f]+ 320a 0100           	mpyf	r0,r2,r4
+0x[0-9a-f]+ 320b 0100           	mpyfr	r0,r2,r4
+0x[0-9a-f]+ 3224 0100           	mpywhfl	r0,r2,r4
+0x[0-9a-f]+ 3225 0100           	mpywhflr	r0,r2,r4
+0x[0-9a-f]+ 3220 0100           	mpywhfm	r0,r2,r4
+0x[0-9a-f]+ 3221 0100           	mpywhfmr	r0,r2,r4
+0x[0-9a-f]+ 321c 0100           	mpywhl	r0,r2,r4
+0x[0-9a-f]+ 321e 0100           	mpywhul	r0,r2,r4
+0x[0-9a-f]+ 3215 0100           	msubdf	r0,r2,r4
+0x[0-9a-f]+ 320e 0100           	msubf	r0,r2,r4
+0x[0-9a-f]+ 320f 0100           	msubfr	r0,r2,r4
+0x[0-9a-f]+ 282f 0086           	negsh	r0,r2
+0x[0-9a-f]+ 282f 0099           	normacc	r0,r2
+0x[0-9a-f]+ 282f 0083           	rndh	r0,r2
+0x[0-9a-f]+ 282f 0082           	sath	r0,r2
+0x[0-9a-f]+ 2a0d 8100           	setacc	r0,r2,r4
+0x[0-9a-f]+ 2a2f 003f           	sqrtacc	r0
+0x[0-9a-f]+ 282f 00a8           	vabs2h	r0,r2
+0x[0-9a-f]+ 282f 00a9           	vabss2h	r0,r2
+0x[0-9a-f]+ 2a24 0100           	vadd4b	r0,r2,r4
+0x[0-9a-f]+ 2a14 8100           	vadds2h	r0,r2,r4
+0x[0-9a-f]+ 2a16 8100           	vaddsubs2h	r0,r2,r4
+0x[0-9a-f]+ 2a0d 0100           	valgn2h	r0,r2,r4
+0x[0-9a-f]+ 2a21 0100           	vasl2h	r0,r2,r4
+0x[0-9a-f]+ 2a21 8100           	vasls2h	r0,r2,r4
+0x[0-9a-f]+ 2a22 0100           	vasr2h	r0,r2,r4
+0x[0-9a-f]+ 2a22 8100           	vasrs2h	r0,r2,r4
+0x[0-9a-f]+ 2a23 8100           	vasrsr2h	r0,r2,r4
+0x[0-9a-f]+ 282f 00a4           	vext2bhl	r0,r2
+0x[0-9a-f]+ 282f 00a5           	vext2bhm	r0,r2
+0x[0-9a-f]+ 2a23 0100           	vlsr2h	r0,r2,r4
+0x[0-9a-f]+ 2a1e 0100           	vmac2h	r0,r2,r4
+0x[0-9a-f]+ 2a1e 8100           	vmac2hf	r0,r2,r4
+0x[0-9a-f]+ 2a1f 8100           	vmac2hfr	r0,r2,r4
+0x[0-9a-f]+ 3211 0100           	vmac2hnfr	r0,r2,r4
+0x[0-9a-f]+ 2a1f 0100           	vmac2hu	r0,r2,r4
+0x[0-9a-f]+ 2a24 8100           	vmax2h	r0,r2,r4
+0x[0-9a-f]+ 2a25 8100           	vmin2h	r0,r2,r4
+0x[0-9a-f]+ 2a1c 0100           	vmpy2h	r0,r2,r4
+0x[0-9a-f]+ 2a1c 8100           	vmpy2hf	r0,r2,r4
+0x[0-9a-f]+ 2a1d 8100           	vmpy2hfr	r0,r2,r4
+0x[0-9a-f]+ 2a1d 0100           	vmpy2hu	r0,r2,r4
+0x[0-9a-f]+ 2a20 0100           	vmpy2hwf	r0,r2,r4
+0x[0-9a-f]+ 3204 0100           	vmsub2hf	r0,r2,r4
+0x[0-9a-f]+ 3203 0100           	vmsub2hfr	r0,r2,r4
+0x[0-9a-f]+ 3211 8100           	vmsub2hnfr	r0,r2,r4
+0x[0-9a-f]+ 282f 00aa           	vneg2h	r0,r2
+0x[0-9a-f]+ 282f 00ab           	vnegs2h	r0,r2
+0x[0-9a-f]+ 282f 00ac           	vnorm2h	r0,r2
+0x[0-9a-f]+ 282f 00a2           	vrep2hl	r0,r2
+0x[0-9a-f]+ 282f 00a3           	vrep2hm	r0,r2
+0x[0-9a-f]+ 282f 00a6           	vsext2bhl	r0,r2
+0x[0-9a-f]+ 282f 00a7           	vsext2bhm	r0,r2
+0x[0-9a-f]+ 2a25 0100           	vsub4b	r0,r2,r4
+0x[0-9a-f]+ 2a17 8100           	vsubadds2h	r0,r2,r4
+0x[0-9a-f]+ 2a15 8100           	vsubs2h	r0,r2,r4
diff --git a/gas/testsuite/gas/arc/dsp.s b/gas/testsuite/gas/arc/dsp.s
new file mode 100644
index 0000000..a085bc5
--- /dev/null
+++ b/gas/testsuite/gas/arc/dsp.s
@@ -0,0 +1,90 @@
+#Test if disassembler correctly prints DSP instructions.
+	abssh		r0,r2
+	aslacc		r0
+	aslsacc		r0
+	asrsr		r0,r2,r4
+	cbflyhf0r	r0,r2,r4
+	cbflyhf1r	r0,r2
+	cmacchfr	r0,r2,r4
+	cmacchnfr	r0,r2,r4
+	cmachfr		r0,r2,r4
+	cmachnfr	r0,r2,r4
+	cmpychfr	r0,r2,r4
+	cmpychnfr	r0,r2,r4
+	cmpyhfmr	r0,r2,r4
+	cmpyhfr		r0,r2,r4
+	cmpyhnfr	r0,r2,r4
+	divacc		r0
+	dmachbl		r0,r2,r4
+	dmachbm		r0,r2,r4
+	dmachf		r0,r2,r4
+	dmachfr		r0,r2,r4
+	dmpyhbl		r0,r2,r4
+	dmpyhbm		r0,r2,r4
+	dmpyhf		r0,r2,r4
+	dmpyhfr		r0,r2,r4
+	dmpyhwf		r0,r2,r4
+	flagacc		r0
+	getacc		r0,r2
+	macf		r0,r2,r4
+	macfr		r0,r2,r4
+	macwhfm		r0,r2,r4
+	macwhfmr	r0,r2,r4
+	macwhl		r0,r2,r4
+	macwhul		r0,r2,r4
+	mpyf		r0,r2,r4
+	mpyfr		r0,r2,r4
+	mpywhfl		r0,r2,r4
+	mpywhflr	r0,r2,r4
+	mpywhfm		r0,r2,r4
+	mpywhfmr	r0,r2,r4
+	mpywhl		r0,r2,r4
+	mpywhul		r0,r2,r4
+	msubdf		r0,r2,r4
+	msubf		r0,r2,r4
+	msubfr		r0,r2,r4
+	negsh		r0,r2
+	normacc		r0,r2
+	rndh		r0,r2
+	sath		r0,r2
+	setacc		r0,r2,r4
+	sqrtacc		r0
+	vabs2h		r0,r2
+	vabss2h		r0,r2
+	vadd4b		r0,r2,r4
+	vadds2h		r0,r2,r4
+	vaddsubs2h	r0,r2,r4
+	valgn2h		r0,r2,r4
+	vasl2h		r0,r2,r4
+	vasls2h		r0,r2,r4
+	vasr2h		r0,r2,r4
+	vasrs2h		r0,r2,r4
+	vasrsr2h	r0,r2,r4
+	vext2bhl	r0,r2
+	vext2bhm	r0,r2
+	vlsr2h		r0,r2,r4
+	vmac2h		r0,r2,r4
+	vmac2hf		r0,r2,r4
+	vmac2hfr	r0,r2,r4
+	vmac2hnfr	r0,r2,r4
+	vmac2hu		r0,r2,r4
+	vmax2h		r0,r2,r4
+	vmin2h		r0,r2,r4
+	vmpy2h		r0,r2,r4
+	vmpy2hf		r0,r2,r4
+	vmpy2hfr	r0,r2,r4
+	vmpy2hu		r0,r2,r4
+	vmpy2hwf	r0,r2,r4
+	vmsub2hf	r0,r2,r4
+	vmsub2hfr	r0,r2,r4
+	vmsub2hnfr	r0,r2,r4
+	vneg2h		r0,r2
+	vnegs2h		r0,r2
+	vnorm2h		r0,r2
+	vrep2hl		r0,r2
+	vrep2hm		r0,r2
+	vsext2bhl	r0,r2
+	vsext2bhm	r0,r2
+	vsub4b		r0,r2,r4
+	vsubadds2h	r0,r2,r4
+	vsubs2h		r0,r2,r4
diff --git a/gas/testsuite/gas/arc/fpu.d b/gas/testsuite/gas/arc/fpu.d
new file mode 100644
index 0000000..ab805da
--- /dev/null
+++ b/gas/testsuite/gas/arc/fpu.d
@@ -0,0 +1,29 @@
+#as: -mcpu=archs
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arc.*
+
+
+Disassembly of section .text:
+0x[0-9a-f]+ 3208 0100           	fcvt32	r0,r2,r4
+0x[0-9a-f]+ 3209 0100           	fcvt32_64	r0,r2,r4
+0x[0-9a-f]+ 3238 0100           	fcvt64	r0,r2,r4
+0x[0-9a-f]+ 3239 0100           	fcvt64_32	r0,r2,r4
+0x[0-9a-f]+ 3231 0100           	fdadd	r0,r2,r4
+0x[0-9a-f]+ 3033 8080           	fdcmp	r0,r2
+0x[0-9a-f]+ 3034 8080           	fdcmpf	r0,r2
+0x[0-9a-f]+ 3237 0100           	fddiv	r0,r2,r4
+0x[0-9a-f]+ 3235 0100           	fdmadd	r0,r2,r4
+0x[0-9a-f]+ 3236 0100           	fdmsub	r0,r2,r4
+0x[0-9a-f]+ 3230 0100           	fdmul	r0,r2,r4
+0x[0-9a-f]+ 302f 0081           	fdsqrt	r0,r2
+0x[0-9a-f]+ 3232 0100           	fdsub	r0,r2,r4
+0x[0-9a-f]+ 3201 0100           	fsadd	r0,r2,r4
+0x[0-9a-f]+ 3003 8080           	fscmp	r0,r2
+0x[0-9a-f]+ 3004 8080           	fscmpf	r0,r2
+0x[0-9a-f]+ 3207 0100           	fsdiv	r0,r2,r4
+0x[0-9a-f]+ 3205 0100           	fsmadd	r0,r2,r4
+0x[0-9a-f]+ 3206 0100           	fsmsub	r0,r2,r4
+0x[0-9a-f]+ 3200 0100           	fsmul	r0,r2,r4
+0x[0-9a-f]+ 302f 0080           	fssqrt	r0,r2
+0x[0-9a-f]+ 3202 0100           	fssub	r0,r2,r4
diff --git a/gas/testsuite/gas/arc/fpu.s b/gas/testsuite/gas/arc/fpu.s
new file mode 100644
index 0000000..78c18bf
--- /dev/null
+++ b/gas/testsuite/gas/arc/fpu.s
@@ -0,0 +1,24 @@
+# Test if all fpu ops are correctly disassembled as they share the
+# same opcode space with FPX instructions.
+	fcvt32		r0,r2,r4
+	fcvt32_64	r0,r2,r4
+	fcvt64		r0,r2,r4
+	fcvt64_32	r0,r2,r4
+	fdadd		r0,r2,r4
+	fdcmp		r0,r2
+	fdcmpf		r0,r2
+	fddiv		r0,r2,r4
+	fdmadd		r0,r2,r4
+	fdmsub		r0,r2,r4
+	fdmul		r0,r2,r4
+	fdsqrt		r0,r2
+	fdsub		r0,r2,r4
+	fsadd		r0,r2,r4
+	fscmp		r0,r2
+	fscmpf		r0,r2
+	fsdiv		r0,r2,r4
+	fsmadd		r0,r2,r4
+	fsmsub		r0,r2,r4
+	fsmul		r0,r2,r4
+	fssqrt		r0,r2
+	fssub		r0,r2,r4
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index 1d1dcd8..35dac80 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -25,8 +25,11 @@
 #include <assert.h>
 #include "dis-asm.h"
 #include "opcode/arc.h"
+#include "elf/arc.h"
 #include "arc-dis.h"
 #include "arc-ext.h"
+#include "elf-bfd.h"
+#include "libiberty.h"
 
 /* Structure used to iterate over, and extract the values for, operands of
    an opcode.  */
@@ -81,6 +84,16 @@ static const char * const regnames[64] =
   "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
 };
 
+/* This structure keeps track which instruction (class) should be
+   ignored durring disassembling.  */
+
+typedef struct skipclass
+{
+  insn_class_t     insn_class;
+  insn_subclass_t  subclass;
+  struct skipclass *nxt;
+} skipclass_t, *linkclass;
+
 /* Macros section.  */
 
 #ifdef DEBUG
@@ -101,6 +114,95 @@ static const char * const regnames[64] =
 
 /* Functions implementation.  */
 
+/* Return TRUE when two classes are not opcode conflicting.  */
+
+static bfd_boolean
+is_compatible_p (insn_class_t classA,
+		 insn_subclass_t sclassA,
+		 insn_class_t classB,
+		 insn_subclass_t sclassB)
+{
+  switch (classA)
+    {
+    case DSP:
+      if (sclassB == DPX)
+	return FALSE;
+      break;
+    default:
+      break;
+    }
+
+  switch (sclassA)
+    {
+    case DPX:
+      if (classB == DSP)
+	return FALSE;
+      break;
+    default:
+      break;
+    }
+  return TRUE;
+}
+
+/* Add new element to conflict list.  */
+
+static linkclass
+new_element (insn_class_t insn_class,
+	     insn_subclass_t subclass,
+	     linkclass pskiplist)
+{
+  linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
+
+  if (t == NULL)
+    return NULL; /* Couldn't allocate memory.  */
+
+  t->insn_class = insn_class;
+  t->subclass = subclass;
+  t->nxt = pskiplist;
+  return t;
+}
+
+/* Return TRUE if we need to skip the opcode from beeing
+   disassembled.  */
+
+static bfd_boolean
+skip_class_p (const struct arc_opcode *opcode,
+	      skipclass_t **ppskiplist)
+{
+  linkclass t = *ppskiplist;
+  bfd_boolean addme = TRUE;
+
+  while (t != NULL
+	 && is_compatible_p (t->insn_class, t->subclass,
+			     opcode->insn_class, opcode->subclass))
+    {
+      if ((t->insn_class == opcode->insn_class)
+	  && (t->subclass == opcode->subclass))
+	addme = FALSE;
+      t = t->nxt;
+    }
+
+  /* If we reach the end, then we are compatible.  */
+  if (t == NULL)
+    {
+      if (addme)
+	switch (opcode->insn_class)
+	  {
+	  case DSP:
+	  case FLOAT:
+	    /* Add to the conflict list only the classes which
+	       counts.  */
+	    *ppskiplist = new_element (opcode->insn_class,
+				       opcode->subclass, *ppskiplist);
+	    break;
+	  default:
+	    break;
+	  }
+      return FALSE;
+    }
+  return TRUE;
+}
+
 static bfd_vma
 bfd_getm32 (unsigned int data)
 {
@@ -151,6 +253,7 @@ find_format_from_table (const struct arc_opcode *arc_table,
   const struct arc_opcode *opcode = NULL;
   const unsigned char *opidx;
   const unsigned char *flgidx;
+  static linkclass skipinsn = NULL;
 
   do {
     bfd_boolean invalid = FALSE;
@@ -176,6 +279,9 @@ find_format_from_table (const struct arc_opcode *arc_table,
     if (!(opcode->cpu & isa_mask))
       continue;
 
+    if (skip_class_p (opcode, &skipinsn))
+      continue;
+
     *has_limm = FALSE;
 
     /* Possible candidate, check the operands.  */
@@ -716,11 +822,15 @@ print_insn_arc (bfd_vma memaddr,
   const struct arc_operand *operand;
   int value;
   struct arc_operand_iterator iter;
+  Elf_Internal_Ehdr *header = NULL;
 
   memset (&iter, 0, sizeof (iter));
   lowbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
   highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
 
+  if (info->section && info->section->owner)
+    header = elf_elfheader (info->section->owner);
+
   switch (info->mach)
     {
     case bfd_mach_arc_arc700:
@@ -733,7 +843,8 @@ print_insn_arc (bfd_vma memaddr,
 
     case bfd_mach_arc_arcv2:
     default:
-      isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
+      isa_mask = ((header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS) ?
+	ARC_OPCODE_ARCv2HS : ARC_OPCODE_ARCv2EM;
       break;
     }
 
-- 
1.9.1


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