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 Nick,

I have updated the patch as you suggested.  Now we get a warning if we
disassemble a opcode that may be shared across current CPU template.
As we have those opcodes conflicting only for Major 0x06, I did added
this condition as well, just for speed purposes.

Additional tests are added in gas/testsuite and binutils/testsuite.
The one in the binutils is testing for the warning feature of the
disassembler.

Please let me know if you have questions,
Claudiu

Original message:

ARC processors may reuse opcodes for different instructions.  This
patch is improving the selection of the instructions when
disassembling by discriminating the ARCHS versus ARCEM cpus, and using
switches for selecting which opcode conflicting class of instructions
to be preferred when disassembling.

gas/
2016-07-20  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.
	* testsuite/gas/arc/ext2op.d: Add specific disassembler option.
	* testsuite/gas/arc/ext3op.d: Likewise.
	* testsuite/gas/arc/tdpfp.d: Likewise.
	* testsuite/gas/arc/tfpuda.d: Likewise.

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

	* arc-dis.c (skipclass): New structure.
	(decodelist): New variable.
	(is_compatible_p): New function.
	(new_element): Likewise.
	(skip_class_p): Likewise.
	(find_format_from_table): Use skip_class_p function.
	(find_format): Decode first the extension instructions.
	(print_insn_arc): Select either ARCEM or ARCHS based on elf
	e_flags.
	(parse_option): New function.
	(parse_disassembler_options): Likewise.
	(print_arc_disassembler_options): Likewise.
	(print_insn_arc): Use parse_disassembler_options function.  Proper
	select ARCv2 cpu variant.
	* disassemble.c (disassembler_usage): Add ARC disassembler
	options.

binutils/
2016-07-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* doc/binutils.texi (objdump): Add ARC disassembler options.
	* testsuite/binutils-all/arc/dsp.s: New file.
	* testsuite/binutils-all/arc/objdump.exp: Likewise.

include/
2016-07-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* dis-asm.h: Declare print_arc_disassembler_options.
---
 binutils/doc/binutils.texi                      |   9 +
 binutils/testsuite/binutils-all/arc/dsp.s       |   5 +
 binutils/testsuite/binutils-all/arc/objdump.exp |  52 ++++
 gas/testsuite/gas/arc/dsp.d                     |  96 ++++++++
 gas/testsuite/gas/arc/dsp.s                     |  90 +++++++
 gas/testsuite/gas/arc/ext2op.d                  |   2 +-
 gas/testsuite/gas/arc/ext3op.d                  |   2 +-
 gas/testsuite/gas/arc/fpu.d                     |  29 +++
 gas/testsuite/gas/arc/fpu.s                     |  24 ++
 gas/testsuite/gas/arc/tdpfp.d                   |   2 +-
 gas/testsuite/gas/arc/tfpuda.d                  |   2 +-
 include/dis-asm.h                               |   1 +
 opcodes/arc-dis.c                               | 305 +++++++++++++++++++++---
 opcodes/disassemble.c                           |   3 +
 14 files changed, 588 insertions(+), 34 deletions(-)
 create mode 100644 binutils/testsuite/binutils-all/arc/dsp.s
 create mode 100644 binutils/testsuite/binutils-all/arc/objdump.exp
 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/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 5a004a3..1b64914 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2313,6 +2313,15 @@ ROM dumps).  In these cases, the function entry mask would otherwise
 be decoded as VAX instructions, which would probably lead the rest
 of the function being wrongly disassembled.
 
+For ARC, @option{dsp} controls the printing of DSP instructions,
+@option{spfp} selects the printing of FPX single precision FP
+instructions, @option{dpfp} selects the printing of FPX double
+precision FP instructions, @option{quarkse_em} selects the printing of
+special QuarkSE-EM instructions, @option{fpuda} selects the printing
+of double precision assist instructions, @option{fpus} selects the
+printing of FPU single precision FP instructions, while @option{fpud}
+selects the printing of FPU souble precision FP instructions.
+
 @item -p
 @itemx --private-headers
 Print information that is specific to the object file format.  The exact
diff --git a/binutils/testsuite/binutils-all/arc/dsp.s b/binutils/testsuite/binutils-all/arc/dsp.s
new file mode 100644
index 0000000..8cca446
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arc/dsp.s
@@ -0,0 +1,5 @@
+	.cpu EM
+	.text
+	vmac2hnfr	r0,r2,r4
+	cmacchfr	r0,r2,r4
+	cmacchnfr	r0,r2,r4
diff --git a/binutils/testsuite/binutils-all/arc/objdump.exp b/binutils/testsuite/binutils-all/arc/objdump.exp
new file mode 100644
index 0000000..43df31b
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arc/objdump.exp
@@ -0,0 +1,52 @@
+#   Copyright (C) 2016 Free Software Foundation, Inc.
+
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+if {![istarget "arc*-*-*"]} then {
+  return
+}
+
+if {[which $OBJDUMP] == 0} then {
+    perror "$OBJDUMP does not exist"
+    return
+}
+
+send_user "Version [binutil_version $OBJDUMP]"
+
+###########################
+# Set up the test of dsp.s
+###########################
+
+if {![binutils_assemble $srcdir/$subdir/dsp.s tmpdir/dsp.o]} then {
+    return
+}
+
+if [is_remote host] {
+    set objfile [remote_download host tmpdir/dsp.o]
+} else {
+    set objfile tmpdir/dsp.o
+}
+
+# Make sure that Warning message is in
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS --disassemble $objfile"]
+
+set want "Warning: disassembly.*dsubh12\[ \t\]*r0,r2,r4.*dmulh12.f\[ \t\]*r0,r2,r4.*dmulh11.f"
+
+if [regexp $want $got] then {
+    pass "Warning test"
+} else {
+    fail "Warning test"
+}
diff --git a/gas/testsuite/gas/arc/dsp.d b/gas/testsuite/gas/arc/dsp.d
new file mode 100644
index 0000000..22961ae
--- /dev/null
+++ b/gas/testsuite/gas/arc/dsp.d
@@ -0,0 +1,96 @@
+#as: -mcpu=arcem
+#objdump: -dr --prefix-addresses --show-raw-insn -M dsp
+
+.*: +file format .*arc.*
+
+
+Disassembly of section .text:
+0x[0-9a-f]+ 3211 0100           	vmac2hnfr	r0,r2,r4
+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]+ 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..2847af6
--- /dev/null
+++ b/gas/testsuite/gas/arc/dsp.s
@@ -0,0 +1,90 @@
+#Test if disassembler correctly prints DSP instructions.
+	vmac2hnfr	r0,r2,r4
+	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
+	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/ext2op.d b/gas/testsuite/gas/arc/ext2op.d
index 144989e..00ef6ac 100644
--- a/gas/testsuite/gas/arc/ext2op.d
+++ b/gas/testsuite/gas/arc/ext2op.d
@@ -1,5 +1,5 @@
 #as: -mcpu=arcem
-#objdump: -dr
+#objdump: -dr -M quarkse_em
 
 .*: +file format .*arc.*
 
diff --git a/gas/testsuite/gas/arc/ext3op.d b/gas/testsuite/gas/arc/ext3op.d
index 926a13c..7a63f14 100644
--- a/gas/testsuite/gas/arc/ext3op.d
+++ b/gas/testsuite/gas/arc/ext3op.d
@@ -1,5 +1,5 @@
 #as: -mcpu=arcem
-#objdump: -dr
+#objdump: -dr -M quarkse_em
 
 .*: +file format .*arc.*
 
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/gas/testsuite/gas/arc/tdpfp.d b/gas/testsuite/gas/arc/tdpfp.d
index 6475ebc..a2edb0e 100644
--- a/gas/testsuite/gas/arc/tdpfp.d
+++ b/gas/testsuite/gas/arc/tdpfp.d
@@ -1,5 +1,5 @@
 #as:-mcpu=arcem -mdpfp
-#objdump: -dr
+#objdump: -dr -M dpfp
 #source: tfpx.s
 
 .*: +file format .*arc.*
diff --git a/gas/testsuite/gas/arc/tfpuda.d b/gas/testsuite/gas/arc/tfpuda.d
index a6645a5..640500e 100644
--- a/gas/testsuite/gas/arc/tfpuda.d
+++ b/gas/testsuite/gas/arc/tfpuda.d
@@ -1,5 +1,5 @@
 #as:-mcpu=arcem -mfpuda
-#objdump: -dr
+#objdump: -dr -M fpuda
 #source: tfpx.s
 
 .*: +file format .*arc.*
diff --git a/include/dis-asm.h b/include/dis-asm.h
index 60bbc8d..05bfa37 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -328,6 +328,7 @@ extern void print_i386_disassembler_options (FILE *);
 extern void print_mips_disassembler_options (FILE *);
 extern void print_ppc_disassembler_options (FILE *);
 extern void print_arm_disassembler_options (FILE *);
+extern void print_arc_disassembler_options (FILE *);
 extern void parse_arm_disassembler_option (char *);
 extern void print_s390_disassembler_options (FILE *);
 extern int  get_arm_regname_num_options (void);
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index 1d1dcd8..c79724c 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -25,8 +25,12 @@
 #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"
+#include "opintl.h"
 
 /* Structure used to iterate over, and extract the values for, operands of
    an opcode.  */
@@ -81,6 +85,20 @@ 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;
+
+/* Intial classes of instructions to be consider first when
+   disassembling.  */
+static linkclass decodelist = NULL;
+
 /* Macros section.  */
 
 #ifdef DEBUG
@@ -101,6 +119,107 @@ 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 plist)
+{
+  linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
+
+  assert (t != NULL);
+
+  t->insn_class = insn_class;
+  t->subclass = subclass;
+  t->nxt = plist;
+  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 **pplist)
+{
+  linkclass t = *pplist;
+  bfd_boolean addme = TRUE;
+
+  /* Check opcode for major 0x06, return if it is not in.  */
+  if (OPCODE (opcode->opcode) != 0x06)
+    return FALSE;
+
+  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)
+    {
+      /* Even if we do not precisely know the if the right mnemonics
+	 is correctly displayed, keep the disassmbled code class
+	 consistent.  */
+      if (addme)
+	{
+	switch (opcode->insn_class)
+	  {
+	  case DSP:
+	  case FLOAT:
+	    /* Add to the conflict list only the classes which
+	       counts.  */
+	    *pplist = new_element (opcode->insn_class,
+				   opcode->subclass, *pplist);
+	    /* Warn if we have to decode an opcode and no preferred
+	       classes is chosen.  */
+	    fprintf (stderr, _("Warning: disassembly unreliable \
+- possible wrong mnemonic chosen\n"));
+	    break;
+	  default:
+	    break;
+	  }
+	}
+      return FALSE;
+    }
+  return TRUE;
+}
+
 static bfd_vma
 bfd_getm32 (unsigned int data)
 {
@@ -144,8 +263,11 @@ special_flag_p (const char *opname,
 
 static const struct arc_opcode *
 find_format_from_table (const struct arc_opcode *arc_table,
-                        unsigned *insn, unsigned int insn_len,
-                        unsigned isa_mask, bfd_boolean *has_limm)
+                        unsigned *insn,
+			unsigned int insn_len,
+                        unsigned isa_mask,
+			bfd_boolean *has_limm,
+			bfd_boolean overlaps)
 {
   unsigned int i = 0;
   const struct arc_opcode *opcode = NULL;
@@ -248,7 +370,12 @@ find_format_from_table (const struct arc_opcode *arc_table,
     if (invalid)
       continue;
 
-    /* The instruction is valid.  */
+    if ((insn_len == 4)
+	&& overlaps
+	&& skip_class_p (opcode, &decodelist))
+      continue;
+
+   /* The instruction is valid.  */
     return opcode;
   } while (opcode->mask);
 
@@ -349,39 +476,35 @@ find_format (bfd_vma memaddr, unsigned *insn, unsigned int *insn_len,
              const struct arc_opcode **opcode_result,
              struct arc_operand_iterator *iter)
 {
-  const struct arc_opcode *opcode;
+  const struct arc_opcode *opcode = NULL;
   bfd_boolean needs_limm;
+  const extInstruction_t *einsn;
 
-  /* Find the first match in the opcode table.  */
-  opcode = find_format_from_table (arc_opcodes, insn, *insn_len,
-                                   isa_mask, &needs_limm);
-
-  if (opcode == NULL)
+  /* First, try the extension instructions.  */
+  einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
+  if (einsn != NULL)
     {
-      const extInstruction_t *einsn;
-
-      /* No instruction found.  Try the extensions.  */
-      einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
-      if (einsn != NULL)
+      const char *errmsg = NULL;
+      opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
+      if (opcode == NULL)
 	{
-	  const char *errmsg = NULL;
-	  opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
-	  if (opcode == NULL)
-	    {
-	      (*info->fprintf_func) (info->stream,
-				     "An error occured while "
-				     "generating the extension instruction "
-				     "operations");
-              *opcode_result = NULL;
-	      return FALSE;
-	    }
-
-	  opcode = find_format_from_table (opcode, insn, *insn_len,
-                                           isa_mask, &needs_limm);
-	  assert (opcode != NULL);
+	  (*info->fprintf_func) (info->stream,
+				 "An error occured while "
+				 "generating the extension instruction "
+				 "operations");
+	  *opcode_result = NULL;
+	  return FALSE;
 	}
+
+      opcode = find_format_from_table (opcode, insn, *insn_len,
+				       isa_mask, &needs_limm, FALSE);
     }
 
+  /* Then, try finding the first match in the opcode table.  */
+  if (opcode == NULL)
+    opcode = find_format_from_table (arc_opcodes, insn, *insn_len,
+				     isa_mask, &needs_limm, TRUE);
+
   if (needs_limm && opcode != NULL)
     {
       bfd_byte buffer[4];
@@ -697,6 +820,76 @@ operand_iterator_next (struct arc_operand_iterator *iter,
   return TRUE;
 }
 
+/* Helper for parsing the options.  */
+
+static void
+parse_option (char *option)
+{
+  if (CONST_STRNEQ (option, "dsp"))
+    {
+      decodelist = new_element (DSP, NONE, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "spfp"))
+    {
+      decodelist = new_element (FLOAT, SPX, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "dpfp"))
+    {
+      decodelist = new_element (FLOAT, DPX, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "quarkse_em"))
+    {
+      decodelist = new_element (FLOAT, QUARKSE, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "fpuda"))
+    {
+      decodelist = new_element (FLOAT, DPA, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "fpud"))
+    {
+      decodelist = new_element (FLOAT, SP, decodelist);
+      decodelist = new_element (FLOAT, CVT, decodelist);
+      return;
+    }
+  if (CONST_STRNEQ (option, "fpus"))
+    {
+      decodelist = new_element (FLOAT, DP, decodelist);
+      decodelist = new_element (FLOAT, CVT, decodelist);
+      return;
+    }
+
+  fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
+}
+
+/* Go over the options list and parse it.  */
+
+static void
+parse_disassembler_options (char *options)
+{
+  if (options == NULL)
+    return;
+
+  while (*options)
+    {
+      /* Skip empty options.  */
+      if (*options == ',')
+	{
+	  ++ options;
+	  continue;
+	}
+
+      parse_option (options);
+
+      while (*options != ',' && *options != '\0')
+	++ options;
+    }
+}
+
 /* Disassemble ARC instructions.  */
 
 static int
@@ -716,11 +909,23 @@ print_insn_arc (bfd_vma memaddr,
   const struct arc_operand *operand;
   int value;
   struct arc_operand_iterator iter;
+  Elf_Internal_Ehdr *header = NULL;
+
+  if (info->disassembler_options)
+    {
+      parse_disassembler_options (info->disassembler_options);
+
+      /* Avoid repeated parsing of the options.  */
+      info->disassembler_options = 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 +938,15 @@ print_insn_arc (bfd_vma memaddr,
 
     case bfd_mach_arc_arcv2:
     default:
-      isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
+      isa_mask = ARC_OPCODE_ARCv2EM;
+      if ((header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
+	{
+	  isa_mask = ARC_OPCODE_ARCv2HS;
+	  /* FPU instructions are not extensions for HS.  */
+	  decodelist = new_element (FLOAT, SP, decodelist);
+	  decodelist = new_element (FLOAT, DP, decodelist);
+	  decodelist = new_element (FLOAT, CVT, decodelist);
+	}
       break;
     }
 
@@ -1042,6 +1255,38 @@ arcAnalyzeInstr (bfd_vma memaddr,
   return ret;
 }
 
+void
+print_arc_disassembler_options (FILE *stream)
+{
+  fprintf (stream, _("\n\
+The following ARC specific disassembler options are supported for use \n\
+with -M switch (multiple options should be separated by commas):\n"));
+
+  fprintf (stream, _("\n\
+  dsp             Recognize DSP instructions.\n"));
+
+  fprintf (stream, _("\n\
+  spfp            Recognize FPX SP instructions.\n"));
+
+  fprintf (stream, _("\n\
+  dpfp            Recognize FPX DP instructions.\n"));
+
+  fprintf (stream, _("\n\
+  quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
+
+  fprintf (stream, _("\n\
+  fpuda           Recognize double assist FPU instructions.\n"));
+
+  fprintf (stream, _("\n\
+  fpus            Recognize single precision FPU instructions.\n"));
+
+  fprintf (stream, _("\n\
+  fpud            Recognize double precision FPU instructions.\n"));
+
+  fprintf (stream, _("\n"));
+}
+
+
 /* Local variables:
    eval: (c-set-style "gnu")
    indent-tabs-mode: t
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index b818d8b..45ae34e 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -547,6 +547,9 @@ disassembler_usage (FILE *stream ATTRIBUTE_UNUSED)
 #ifdef ARCH_aarch64
   print_aarch64_disassembler_options (stream);
 #endif
+#ifdef ARCH_arc
+  print_arc_disassembler_options (stream);
+#endif
 #ifdef ARCH_arm
   print_arm_disassembler_options (stream);
 #endif
-- 
1.9.1


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