From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29468 invoked by alias); 6 Aug 2012 22:42:37 -0000 Received: (qmail 29460 invoked by uid 22791); 6 Aug 2012 22:42:35 -0000 X-SWARE-Spam-Status: No, hits=-4.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,KHOP_RCVD_TRUST,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-pb0-f41.google.com (HELO mail-pb0-f41.google.com) (209.85.160.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 06 Aug 2012 22:42:20 +0000 Received: by pbbjt11 with SMTP id jt11so3037310pbb.0 for ; Mon, 06 Aug 2012 15:42:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:message-id:from:to:subject:emacs:x-gm-message-state; bh=GpTfJXYyhHRt4W49big6/UOdb/eNuWkHhoTCrpZJZEk=; b=ITwpLsNgjr2EDhnTW9RhEmHZzF/mBQmSIef95zHino1+Qkf4m5UemGG0I4Xvl/WKhG YHAMS4lxxtZADRikI+nyQIQX5fQ112C2MIDGHjN+q6Id22x+OFzoBjVJnIAim4cXvZlG 34VNUzb9cWjtFq2nr1ZWjGELLgMFrYhbghs9nLRNYuUxFAPTkt/5VPDrHb5DGNuIsoJE QycyX6TYHZqO2TXHmc+amDUQevpXpcoiOWc4/mu2prpzAihe6RptT1SfPd1pIqGgg7ey ykSQMR63TVnL06abS1n7b85jMWEjW7j6fsExbUzSduQxrMVdWpI6u/fZH69tRIKHh/9e OKag== Received: by 10.66.83.234 with SMTP id t10mr21351133pay.39.1344292939827; Mon, 06 Aug 2012 15:42:19 -0700 (PDT) Received: by 10.66.83.234 with SMTP id t10mr21351118pay.39.1344292939686; Mon, 06 Aug 2012 15:42:19 -0700 (PDT) Received: from frobland.mtv.corp.google.com.google.com ([2620:0:1000:1b01:6631:50ff:fe3b:961a]) by mx.google.com with ESMTPS id jv6sm9766803pbc.40.2012.08.06.15.42.18 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 06 Aug 2012 15:42:18 -0700 (PDT) Date: Mon, 06 Aug 2012 22:51:00 -0000 Message-Id: From: Roland McGrath To: binutils@sourceware.org Subject: [PATCH] i386-dis: fix decoding of reserved "prefetch" encodings X-Gm-Message-State: ALoCoQnKVnzXBLhsm/TTIJTdprmwmfMwrT0Mj8Tp0QQZxM4JbVc9W683qUcofhSnoeIyvwfX2wJaKD2hZ8esZg0mdCHYWwYYHx8YX6BYU/dXWoLo44xTWukFpHF6Zm77yo1Dy/rSxzwGnL31nFgNwu5jUuTP6r4QyEPZaAR8+baTefoERSXCLfijskroMU7laObK3YDOGaiz Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2012-08/txt/msg00114.txt.bz2 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+ : +\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]+ : +\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+ : +\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]+ : +\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+ : +\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]+ : +\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+ : +\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]+ : +\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 } },