[PATCH] i386-dis: fix decoding of reserved "prefetch" encodings

Roland McGrath mcgrathr@google.com
Mon Aug 6 22:51:00 GMT 2012


When the extra encodings of "prefetch" that the assembler doesn't generate
are used, the disassembler gets confused and loses track of the instruction
boundaries.

This fixes it by decoding those forms.  For the AMD variant I used the
mnemonic "prefetch", because the AMD manual says that the reserved prefetch
types are treated as synonyms for the basic prefetch type (0), for which
the mnemonic is "prefetch".  For the Intel variant, I used the
pseudo-mnemonic "prefetch(bad)", because the Intel manual says that use of
any but the prescribed types "will lead to unpredictable behavior".

Perhaps it would be better for all these to yield a more informative
pseudo-mnemonic such as "prefetch(amdresv4)" or "prefetch(intelresv4)".
I don't have a particular opinion about that.  What I've done here seems
to be consistent with the way we disassemble other redundant encodings.

This adds a new test case just to exhaustively cover these variants in the
disassembler, though there are existing test cases that test some instances
of the prefetch instructions.  There are no 'make check' regressions on
x86_64-linux-gnu.

Ok for trunk?


Thanks,
Roland


gas/testsuite/
	* gas/i386/prefetch.s: New file.
	* gas/i386/prefetch.d: New file.
	* gas/i386/prefetch-intel.d: New file.
	* gas/i386/x86-64-prefetch.d: New file.
	* gas/i386/x86-64-prefetch-intel.d: New file.
	* gas/i386/i386.exp: Run them.

opcodes/
	* i386-dis.c (reg_table): Fill out REG_0F0D table with
	AMD-reserved cases as "prefetch".
	(MOD_0F18_REG_4, MOD_0F18_REG_5): New enum constants.
	(MOD_0F18_REG_6, MOD_0F18_REG_7): Likewise.
	(reg_table): Use those under REG_0F18.
	(mod_table): Add those cases as "prefetch(bad)".

diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 8ad4ceb..fe4f126 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -212,6 +212,8 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "adx-intel"
     run_dump_test "rdseed"
     run_dump_test "rdseed-intel"
+    run_dump_test "prefetch"
+    run_dump_test "prefetch-intel"
 
     # These tests require support for 8 and 16 bit relocs,
     # so we only run them for ELF and COFF targets.
@@ -447,6 +449,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-adx-intel"
     run_dump_test "x86-64-rdseed"
     run_dump_test "x86-64-rdseed-intel"
+    run_dump_test "x86-64-prefetch"
+    run_dump_test "x86-64-prefetch-intel"
 
     if { ![istarget "*-*-aix*"]
       && ![istarget "*-*-beos*"]
diff --git a/gas/testsuite/gas/i386/prefetch-intel.d b/gas/testsuite/gas/i386/prefetch-intel.d
new file mode 100644
index 0000000..2f09adf
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefetch-intel.d
@@ -0,0 +1,27 @@
+#objdump: -dw -Mintel
+#name: i386 prefetch (Intel disassembly)
+#source: prefetch.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <amd_prefetch>:
+\s*[a-f0-9]+:	0f 0d 00             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 08             	prefetchw BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 10             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 18             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 20             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 28             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 30             	prefetch BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 0d 38             	prefetch BYTE PTR \[eax\]
+
+0+[0-9a-f]+ <intel_prefetch>:
+\s*[a-f0-9]+:	0f 18 00             	prefetchnta BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 08             	prefetcht0 BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 10             	prefetcht1 BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 18             	prefetcht2 BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 20             	prefetch\(bad\) BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 28             	prefetch\(bad\) BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 30             	prefetch\(bad\) BYTE PTR \[eax\]
+\s*[a-f0-9]+:	0f 18 38             	prefetch\(bad\) BYTE PTR \[eax\]
diff --git a/gas/testsuite/gas/i386/prefetch.d b/gas/testsuite/gas/i386/prefetch.d
new file mode 100644
index 0000000..9e39814
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefetch.d
@@ -0,0 +1,26 @@
+#objdump: -dw
+#name: i386 prefetch
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <amd_prefetch>:
+\s*[a-f0-9]+:	0f 0d 00             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 08             	prefetchw \(%eax\)
+\s*[a-f0-9]+:	0f 0d 10             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 18             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 20             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 28             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 30             	prefetch \(%eax\)
+\s*[a-f0-9]+:	0f 0d 38             	prefetch \(%eax\)
+
+0+[0-9a-f]+ <intel_prefetch>:
+\s*[a-f0-9]+:	0f 18 00             	prefetchnta \(%eax\)
+\s*[a-f0-9]+:	0f 18 08             	prefetcht0 \(%eax\)
+\s*[a-f0-9]+:	0f 18 10             	prefetcht1 \(%eax\)
+\s*[a-f0-9]+:	0f 18 18             	prefetcht2 \(%eax\)
+\s*[a-f0-9]+:	0f 18 20             	prefetch\(bad\) \(%eax\)
+\s*[a-f0-9]+:	0f 18 28             	prefetch\(bad\) \(%eax\)
+\s*[a-f0-9]+:	0f 18 30             	prefetch\(bad\) \(%eax\)
+\s*[a-f0-9]+:	0f 18 38             	prefetch\(bad\) \(%eax\)
diff --git a/gas/testsuite/gas/i386/prefetch.s b/gas/testsuite/gas/i386/prefetch.s
new file mode 100644
index 0000000..c0f92ae
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefetch.s
@@ -0,0 +1,18 @@
+.macro try opcode:vararg
+	.byte \opcode, 0x00
+	.byte \opcode, 0x08
+	.byte \opcode, 0x10
+	.byte \opcode, 0x18
+	.byte \opcode, 0x20
+	.byte \opcode, 0x28
+	.byte \opcode, 0x30
+	.byte \opcode, 0x38
+.endm
+
+.text
+
+amd_prefetch:
+	try 0x0f, 0x0d
+
+intel_prefetch:
+	try 0x0f, 0x18
diff --git a/gas/testsuite/gas/i386/x86-64-prefetch-intel.d b/gas/testsuite/gas/i386/x86-64-prefetch-intel.d
new file mode 100644
index 0000000..f2c13d0
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-prefetch-intel.d
@@ -0,0 +1,27 @@
+#objdump: -dw -Mintel
+#name: x86-64 prefetch (Intel disassembly)
+#source: prefetch.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <amd_prefetch>:
+\s*[a-f0-9]+:	0f 0d 00             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 08             	prefetchw BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 10             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 18             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 20             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 28             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 30             	prefetch BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 0d 38             	prefetch BYTE PTR \[rax\]
+
+0+[0-9a-f]+ <intel_prefetch>:
+\s*[a-f0-9]+:	0f 18 00             	prefetchnta BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 08             	prefetcht0 BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 10             	prefetcht1 BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 18             	prefetcht2 BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 20             	prefetch\(bad\) BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 28             	prefetch\(bad\) BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 30             	prefetch\(bad\) BYTE PTR \[rax\]
+\s*[a-f0-9]+:	0f 18 38             	prefetch\(bad\) BYTE PTR \[rax\]
diff --git a/gas/testsuite/gas/i386/x86-64-prefetch.d b/gas/testsuite/gas/i386/x86-64-prefetch.d
new file mode 100644
index 0000000..7a570f1
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-prefetch.d
@@ -0,0 +1,27 @@
+#objdump: -dw
+#name: x86-64 prefetch
+#source: prefetch.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <amd_prefetch>:
+\s*[a-f0-9]+:	0f 0d 00             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 08             	prefetchw \(%rax\)
+\s*[a-f0-9]+:	0f 0d 10             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 18             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 20             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 28             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 30             	prefetch \(%rax\)
+\s*[a-f0-9]+:	0f 0d 38             	prefetch \(%rax\)
+
+0+[0-9a-f]+ <intel_prefetch>:
+\s*[a-f0-9]+:	0f 18 00             	prefetchnta \(%rax\)
+\s*[a-f0-9]+:	0f 18 08             	prefetcht0 \(%rax\)
+\s*[a-f0-9]+:	0f 18 10             	prefetcht1 \(%rax\)
+\s*[a-f0-9]+:	0f 18 18             	prefetcht2 \(%rax\)
+\s*[a-f0-9]+:	0f 18 20             	prefetch\(bad\) \(%rax\)
+\s*[a-f0-9]+:	0f 18 28             	prefetch\(bad\) \(%rax\)
+\s*[a-f0-9]+:	0f 18 30             	prefetch\(bad\) \(%rax\)
+\s*[a-f0-9]+:	0f 18 38             	prefetch\(bad\) \(%rax\)
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index da5ede5..47b540e 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -668,6 +668,10 @@ enum
   MOD_0F18_REG_1,
   MOD_0F18_REG_2,
   MOD_0F18_REG_3,
+  MOD_0F18_REG_4,
+  MOD_0F18_REG_5,
+  MOD_0F18_REG_6,
+  MOD_0F18_REG_7,
   MOD_0F20,
   MOD_0F21,
   MOD_0F22,
@@ -2652,6 +2656,12 @@ static const struct dis386 reg_table[][8] = {
   {
     { "prefetch",	{ Mb } },
     { "prefetchw",	{ Mb } },
+    { "prefetch",	{ Mb } },
+    { "prefetch",	{ Mb } },
+    { "prefetch",	{ Mb } },
+    { "prefetch",	{ Mb } },
+    { "prefetch",	{ Mb } },
+    { "prefetch",	{ Mb } },
   },
   /* REG_0F18 */
   {
@@ -2659,6 +2669,10 @@ static const struct dis386 reg_table[][8] = {
     { MOD_TABLE (MOD_0F18_REG_1) },
     { MOD_TABLE (MOD_0F18_REG_2) },
     { MOD_TABLE (MOD_0F18_REG_3) },
+    { MOD_TABLE (MOD_0F18_REG_4) },
+    { MOD_TABLE (MOD_0F18_REG_5) },
+    { MOD_TABLE (MOD_0F18_REG_6) },
+    { MOD_TABLE (MOD_0F18_REG_7) },
   },
   /* REG_0F71 */
   {
@@ -10221,6 +10235,22 @@ static const struct dis386 mod_table[][2] = {
     { "prefetcht2",	{ Mb } },
   },
   {
+    /* MOD_0F18_REG_4 */
+    { "prefetch(bad)",	{ Mb } },
+  },
+  {
+    /* MOD_0F18_REG_5 */
+    { "prefetch(bad)",	{ Mb } },
+  },
+  {
+    /* MOD_0F18_REG_6 */
+    { "prefetch(bad)",	{ Mb } },
+  },
+  {
+    /* MOD_0F18_REG_7 */
+    { "prefetch(bad)",	{ Mb } },
+  },
+  {
     /* MOD_0F20 */
     { Bad_Opcode },
     { "movZ",		{ Rm, Cm } },



More information about the Binutils mailing list