Bug 23025

Summary: inconsistent disassemble of vcvtpd2dq
Product: binutils Reporter: herumi
Component: binutilsAssignee: H.J. Lu <hjl.tools>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 2.30   
Target Milestone: 2.31   
See Also: https://sourceware.org/bugzilla/show_bug.cgi?id=23028
Host: Target:
Build: Last reconfirmed: 2018-04-03 00:00:00
Attachments: target binary for disassemble

Description herumi 2018-04-03 12:28:49 UTC
Created attachment 10930 [details]
target binary for disassemble

objdump(version 2.3.0) shows inconsistent disassemble of vcvtpd2dq.

The results differ before and after the byte sequence 67 62 f1 ff 18 e6 40 04 .

% od -tx1 -Ax vcvtpd2dq.bin
000000 67 c5 fb e6 40 20 67 c5 ff e6 40 20 67 62 f1 ff
000010 18 e6 40 04 67 c5 fb e6 40 20 67 c5 ff e6 40 20

% objdump -M x86-64 -D -b binary -m i386 vcvtpd2dq.bin

vcvtpd2dq.bin:     file format binary

Disassembly of section .data:

00000000 <.data>:
   0:   67 c5 fb e6 40 20       vcvtpd2dqx 0x20(%eax),%xmm0      ; (X)
   6:   67 c5 ff e6 40 20       vcvtpd2dqy 0x20(%eax),%xmm0      ; (Y)
   c:   67 62 f1 ff 18 e6 40    vcvtpd2dq 0x20(%eax){1to2},%xmm0 ; (Z)
  13:   04
  14:   67 c5 fb e6 40 20       vcvtpd2dq 0x20(%eax),%xmm0       ; (X')
  1a:   67 c5 ff e6 40 20       vcvtpd2dq 0x20(%eax),%xmm0       ; (Y')

The results for (X) and (X'), for (Y) and (Y') should be same.
Strangely, the results are correct if the byte sequence for (Z) is omitted.
Comment 1 H.J. Lu 2018-04-03 22:53:16 UTC
I will fix it:

diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index e5791c9a5f..2db38219f8 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -12874,6 +12874,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
   }
       codep++;
       vex.w = *codep & 0x80;
+      vex.b = 0;
       if (address_mode == mode_64bit)
   {
     if (vex.w)
@@ -12930,6 +12931,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
    VEX.vvvv is 1.  */
       vex.register_specifier = (~(*codep >> 3)) & 0xf;
       vex.w = 0;
+      vex.b = 0;
       vex.length = (*codep & 0x4) ? 256 : 128;
       switch ((*codep & 0x3))
   {
Comment 2 Sourceware Commits 2018-04-04 11:43:11 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=caf0678c84b5b55fbc4bcc853954745a4ad8b658

commit caf0678c84b5b55fbc4bcc853954745a4ad8b658
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Apr 4 04:36:44 2018 -0700

    i386: Clear vex instead of vex.evex
    
    "vex" has many fields to control how to decode an instruction.  Clear
    all fields in "vex" before decoding an instruction to avoid using values
    left from the previous instruction.
    
    gas/
    
    	PR binutils/23025
    	* testsuite/gas/i386/prefix.s: Add tests for vcvtpd2dq with
    	VEX and EVEX prefixes.
    	* testsuite/gas/i386/prefix.d: Updated.
    
    opcodes/
    
    	PR binutils/23025
    	* i386-dis.c (get_valid_dis386): Don't set vex.prefix nor vex.w
    	to 0.
    	(print_insn): Clear vex instead of vex.evex.
Comment 3 Sourceware Commits 2018-04-04 13:24:24 UTC
The binutils-2_30-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=aa15ca261023bb03b22a356787786aa5521ce2f8

commit aa15ca261023bb03b22a356787786aa5521ce2f8
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Apr 4 04:36:44 2018 -0700

    i386: Clear vex instead of vex.evex
    
    "vex" has many fields to control how to decode an instruction.  Clear
    all fields in "vex" before decoding an instruction to avoid using values
    left from the previous instruction.
    
    gas/
    
    	PR binutils/23025
    	* testsuite/gas/i386/prefix.s: Add tests for vcvtpd2dq with
    	VEX and EVEX prefixes.
    	* testsuite/gas/i386/prefix.d: Updated.
    
    opcodes/
    
    	PR binutils/23025
    	* i386-dis.c (get_valid_dis386): Don't set vex.prefix nor vex.w
    	to 0.
    	(print_insn): Clear vex instead of vex.evex.
    
    (cherry picked from commit caf0678c84b5b55fbc4bcc853954745a4ad8b658)
Comment 4 H.J. Lu 2018-04-04 13:24:52 UTC
Fixed on master and 2.30 branch.
Comment 5 Sourceware Commits 2018-04-04 15:56:36 UTC
The gdb-8.1-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f13be04ec6cc83947d8c4997aa48296a915b637f

commit f13be04ec6cc83947d8c4997aa48296a915b637f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Apr 4 04:36:44 2018 -0700

    i386: Clear vex instead of vex.evex
    
    "vex" has many fields to control how to decode an instruction.  Clear
    all fields in "vex" before decoding an instruction to avoid using values
    left from the previous instruction.
    
    gas/
    
    	PR gdb/23028
    	PR binutils/23025
    	* testsuite/gas/i386/prefix.s: Add tests for vcvtpd2dq with
    	VEX and EVEX prefixes.
    	* testsuite/gas/i386/prefix.d: Updated.
    
    opcodes/
    
    	PR gdb/23028
    	PR binutils/23025
    	* i386-dis.c (get_valid_dis386): Don't set vex.prefix nor vex.w
    	to 0.
    	(print_insn): Clear vex instead of vex.evex.
    
    (cherry picked from commit caf0678c84b5b55fbc4bcc853954745a4ad8b658)