public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings
@ 2012-08-06 22:51 Roland McGrath
  2012-08-07 17:36 ` H.J. Lu
  0 siblings, 1 reply; 5+ messages in thread
From: Roland McGrath @ 2012-08-06 22:51 UTC (permalink / raw)
  To: binutils

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings
  2012-08-06 22:51 [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings Roland McGrath
@ 2012-08-07 17:36 ` H.J. Lu
  2012-08-07 18:00   ` Roland McGrath
  0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2012-08-07 17:36 UTC (permalink / raw)
  To: Roland McGrath; +Cc: binutils

On Mon, Aug 6, 2012 at 3:42 PM, Roland McGrath <mcgrathr@google.com> wrote:
> 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.
>

Those are marked as NOPs in AMD manual and reserved in Intel
manual.  I don't like "prefetch(bad)".  I can live with "nop/reserved".


-- 
H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings
  2012-08-07 17:36 ` H.J. Lu
@ 2012-08-07 18:00   ` Roland McGrath
  2012-08-07 18:23     ` H.J. Lu
  0 siblings, 1 reply; 5+ messages in thread
From: Roland McGrath @ 2012-08-07 18:00 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

On Tue, Aug 7, 2012 at 10:34 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Those are marked as NOPs in AMD manual and reserved in Intel
> manual.  I don't like "prefetch(bad)".  I can live with "nop/reserved".

Can you cite the manuals you are looking at?

I'm looking at http://support.amd.com/us/Processor_TechDocs/24594_APM_v3.pdf
on page 254:
	The reserved PREFETCH types do not result in an invalid-opcode
	exception if executed.  Instead, for forward compatibility with
	future processors that may implement additional forms of the
	PREFETCH instruction, all reserved PREFETCH types are implemented
	as synonyms of the basic PREFETCH type (the PREFETCH instruction
	with type 000b).
That says they are prefetch, not nop.  That's for the 0f 0d set.

For 0f 18, the same AMD manual's Table A-7 (page 430, in the "Group 16"
row) says "NOP[4]" for these excess encodings but the footnote is:
	4. Reserved prefetch encodings are aliases to the /0 encoding
	   (PREFETCH Exclusive) for future compatibility.
So these Intel reserved opcodes are in fact also prefetch on AMD, not nop,
despite the appearance of "NOP" in the table grid.

So it seems to me the mnemonic ought to have "prefetch" in it somewhere.
How about "prefetch/reserved"?


Thanks,
Roland

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings
  2012-08-07 18:00   ` Roland McGrath
@ 2012-08-07 18:23     ` H.J. Lu
  2012-08-08  7:07       ` Roland McGrath
  0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2012-08-07 18:23 UTC (permalink / raw)
  To: Roland McGrath; +Cc: binutils

On Tue, Aug 7, 2012 at 10:52 AM, Roland McGrath <mcgrathr@google.com> wrote:
> On Tue, Aug 7, 2012 at 10:34 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> Those are marked as NOPs in AMD manual and reserved in Intel
>> manual.  I don't like "prefetch(bad)".  I can live with "nop/reserved".
>
> Can you cite the manuals you are looking at?
>
> I'm looking at http://support.amd.com/us/Processor_TechDocs/24594_APM_v3.pdf
> on page 254:
>         The reserved PREFETCH types do not result in an invalid-opcode
>         exception if executed.  Instead, for forward compatibility with
>         future processors that may implement additional forms of the
>         PREFETCH instruction, all reserved PREFETCH types are implemented
>         as synonyms of the basic PREFETCH type (the PREFETCH instruction
>         with type 000b).
> That says they are prefetch, not nop.  That's for the 0f 0d set.
>
> For 0f 18, the same AMD manual's Table A-7 (page 430, in the "Group 16"
> row) says "NOP[4]" for these excess encodings but the footnote is:
>         4. Reserved prefetch encodings are aliases to the /0 encoding
>            (PREFETCH Exclusive) for future compatibility.
> So these Intel reserved opcodes are in fact also prefetch on AMD, not nop,
> despite the appearance of "NOP" in the table grid.
>
> So it seems to me the mnemonic ought to have "prefetch" in it somewhere.
> How about "prefetch/reserved"?
>

Since it is marked as NOP in AMD table, I prefer nop.  As for aliasing
to PREFETCH Exclusive.  It is just an implementation detail.  A future
processor may alias them to a different NOP, not necessarily
PREFETCH Exclusive.

-- 
H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings
  2012-08-07 18:23     ` H.J. Lu
@ 2012-08-08  7:07       ` Roland McGrath
  0 siblings, 0 replies; 5+ messages in thread
From: Roland McGrath @ 2012-08-08  7:07 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

Committed using "nop/reserved" for the 0f 18 cases.


Thanks,
Roland

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-08-07 18:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-06 22:51 [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings Roland McGrath
2012-08-07 17:36 ` H.J. Lu
2012-08-07 18:00   ` Roland McGrath
2012-08-07 18:23     ` H.J. Lu
2012-08-08  7:07       ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).