This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] [ARC] Improve filtering instructions while disassembling.
- From: Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>
- To: <binutils at sourceware dot org>
- Cc: <Claudiu dot Zissulescu at synopsys dot com>, <Francois dot Bedard at synopsys dot com>, <Cupertino dot Miranda at synopsys dot com>, <nickc at redhat dot com>
- Date: Thu, 14 Jul 2016 16:07:11 +0200
- Subject: [PATCH] [ARC] Improve filtering instructions while disassembling.
- Authentication-results: sourceware.org; auth=none
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