[llvm] r199650 - [x86] Fix 16-bit handling of OpSize bit

David Woodhouse dwmw2 at infradead.org
Mon Jan 20 04:02:36 PST 2014


Author: dwmw2
Date: Mon Jan 20 06:02:35 2014
New Revision: 199650

URL: http://llvm.org/viewvc/llvm-project?rev=199650&view=rev
Log:
[x86] Fix 16-bit handling of OpSize bit

When disassembling in 16-bit mode the meaning of the OpSize bit is
inverted. Instructions found in the IC_OPSIZE context will actually
*not* have the 0x66 prefix, and instructions in the IC context will
have the 0x66 prefix. Make use of the existing special-case handling
for the 0x66 prefix being in the wrong place, to cope with this.

Added:
    llvm/trunk/test/MC/Disassembler/X86/x86-16.txt
Modified:
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=199650&r1=199649&r2=199650&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Mon Jan 20 06:02:35 2014
@@ -971,7 +971,7 @@ static int getID(struct InternalInstruct
     }
   }
   else {
-    if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
+    if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
       attrMask |= ATTR_OPSIZE;
     else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation))
       attrMask |= ATTR_ADSIZE;
@@ -989,7 +989,8 @@ static int getID(struct InternalInstruct
 
   /* The following clauses compensate for limitations of the tables. */
 
-  if (insn->prefixPresent[0x66] && !(attrMask & ATTR_OPSIZE)) {
+  if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
+      !(attrMask & ATTR_OPSIZE)) {
     /*
      * The instruction tables make no distinction between instructions that
      * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a
@@ -1021,7 +1022,8 @@ static int getID(struct InternalInstruct
     specWithOpSizeName =
       x86DisassemblerGetInstrName(instructionIDWithOpsize, miiArg);
 
-    if (is16BitEquivalent(specName, specWithOpSizeName)) {
+    if (is16BitEquivalent(specName, specWithOpSizeName) &&
+        (insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) {
       insn->instructionID = instructionIDWithOpsize;
       insn->spec = specifierForUID(instructionIDWithOpsize);
     } else {

Added: llvm/trunk/test/MC/Disassembler/X86/x86-16.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-16.txt?rev=199650&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/x86-16.txt (added)
+++ llvm/trunk/test/MC/Disassembler/X86/x86-16.txt Mon Jan 20 06:02:35 2014
@@ -0,0 +1,788 @@
+# RUN: llvm-mc --disassemble %s -triple=i686-linux-gnu-code16 | FileCheck %s
+
+# CHECK: movl $305419896, %ebx
+0x66 0xbb 0x78 0x56 0x34 0x12
+
+# CHECK: pause
+0xf3 0x90
+
+# CHECK: sfence
+0x0f 0xae 0xf8
+
+# CHECK: lfence
+0x0f 0xae 0xe8
+
+# CHECK: mfence
+0x0f 0xae 0xf0
+
+# CHECK: stgi
+0x0f 0x01 0xdc
+
+# CHECK: clgi
+0x0f 0x01 0xdd
+
+# CHECK: rdtscp
+0x0f 0x01 0xf9
+
+# CHECK: movl %eax, 16(%ebp)
+0x67 0x66 0x89 0x45 0x10
+
+# CHECK: movl %eax, -16(%ebp)
+0x67 0x66 0x89 0x45 0xf0
+
+# CHECK: testb %bl, %cl
+0x84 0xcb
+
+# CHECK: cmpl %eax, %ebx
+0x66 0x39 0xc3
+
+# CHECK: addw %ax, %ax
+0x01 0xc0
+
+# CHECK: shrl %eax
+0x66 0xd1 0xe8
+
+# CHECK: shll %eax
+0x66 0xd1 0xe0
+
+# CHECK: shll %eax
+0x66 0xd1 0xe0
+
+# CHECK: movb 0, %al
+0xa0 0x00 0x00
+
+# CHECK: movw 0, %ax
+0xa1 0x00 0x00
+
+# CHECK: movl 0, %eax
+0x66 0xa1 0x00 0x00
+
+# CHECK: into
+0xce
+
+# CHECK: int3
+0xcc
+
+# CHECK: int $4
+0xcd 0x04
+
+# CHECK: int $127
+0xcd 0x7f
+
+# CHECK: pushfw
+0x9c
+
+# CHECK: pushfl
+0x66 0x9c
+
+# CHECK: popfw
+0x9d
+
+# CHECK: popfl
+0x66 0x9d
+
+# CHECK: retl
+0x66 0xc3
+
+# CHECK: cmoval %eax, %edx
+0x66 0x0f 0x47 0xd0
+
+# CHECK: cmovael %eax, %edx
+0x66 0x0f 0x43 0xd0
+
+# CHECK: cmovbel %eax, %edx
+0x66 0x0f 0x46 0xd0
+
+# CHECK: cmovbl %eax, %edx
+0x66 0x0f 0x42 0xd0
+
+# CHECK: cmovbw %bx, %bx
+0x0f 0x42 0xdb
+
+# CHECK: cmovbel %eax, %edx
+0x66 0x0f 0x46 0xd0
+
+# CHECK: cmovbl %eax, %edx
+0x66 0x0f 0x42 0xd0
+
+# CHECK: cmovel %eax, %edx
+0x66 0x0f 0x44 0xd0
+
+# CHECK: cmovgl %eax, %edx
+0x66 0x0f 0x4f 0xd0
+
+# CHECK: cmovgel %eax, %edx
+0x66 0x0f 0x4d 0xd0
+
+# CHECK: cmovll %eax, %edx
+0x66 0x0f 0x4c 0xd0
+
+# CHECK: cmovlel %eax, %edx
+0x66 0x0f 0x4e 0xd0
+
+# CHECK: cmovbel %eax, %edx
+0x66 0x0f 0x46 0xd0
+
+# CHECK: cmovnel %eax, %edx
+0x66 0x0f 0x45 0xd0
+
+# CHECK: cmovael %eax, %edx
+0x66 0x0f 0x43 0xd0
+
+# CHECK: cmoval %eax, %edx
+0x66 0x0f 0x47 0xd0
+
+# CHECK: cmovael %eax, %edx
+0x66 0x0f 0x43 0xd0
+
+# CHECK: cmovnel %eax, %edx
+0x66 0x0f 0x45 0xd0
+
+# CHECK: cmovlel %eax, %edx
+0x66 0x0f 0x4e 0xd0
+
+# CHECK: cmovgel %eax, %edx
+0x66 0x0f 0x4d 0xd0
+
+# CHECK: cmovnel %eax, %edx
+0x66 0x0f 0x45 0xd0
+
+# CHECK: cmovlel %eax, %edx
+0x66 0x0f 0x4e 0xd0
+
+# CHECK: cmovll %eax, %edx
+0x66 0x0f 0x4c 0xd0
+
+# CHECK: cmovgel %eax, %edx
+0x66 0x0f 0x4d 0xd0
+
+# CHECK: cmovgl %eax, %edx
+0x66 0x0f 0x4f 0xd0
+
+# CHECK: cmovnol %eax, %edx
+0x66 0x0f 0x41 0xd0
+
+# CHECK: cmovnpl %eax, %edx
+0x66 0x0f 0x4b 0xd0
+
+# CHECK: cmovnsl %eax, %edx
+0x66 0x0f 0x49 0xd0
+
+# CHECK: cmovnel %eax, %edx
+0x66 0x0f 0x45 0xd0
+
+# CHECK: cmovol %eax, %edx
+0x66 0x0f 0x40 0xd0
+
+# CHECK: cmovpl %eax, %edx
+0x66 0x0f 0x4a 0xd0
+
+# CHECK: cmovsl %eax, %edx
+0x66 0x0f 0x48 0xd0
+
+# CHECK: cmovel %eax, %edx
+0x66 0x0f 0x44 0xd0
+
+# CHECK: fmul %st(0)
+0xd8 0xc8
+
+# CHECK: fadd %st(0)
+0xd8 0xc0
+
+# CHECK: fsub %st(0)
+0xd8 0xe0
+
+# CHECK: fsubr %st(0)
+0xd8 0xe8
+
+# CHECK: fdivr %st(0)
+0xd8 0xf8
+
+# CHECK: fdiv %st(0)
+0xd8 0xf0
+
+# CHECK: movl %cs, %eax
+0x66 0x8c 0xc8
+
+# CHECK: movw %cs, %ax
+0x8c 0xc8
+
+# CHECK: movl %cs, (%eax)
+0x67 0x66 0x8c 0x08
+
+# CHECK: movw %cs, (%eax)
+0x67 0x8c 0x08
+
+# CHECK: movl %eax, %cs
+0x66 0x8e 0xc8
+
+# CHECK: movl (%eax), %cs
+0x67 0x66 0x8e 0x08
+
+# CHECK: movw (%eax), %cs
+0x67 0x8e 0x08
+
+# CHECKX: movl %cr0, %eax
+0x0f 0x20 0xc0
+
+# CHECKX: movl %cr1, %eax
+0x0f 0x20 0xc8
+
+# CHECKX: movl %cr2, %eax
+0x0f 0x20 0xd0
+
+# CHECKX: movl %cr3, %eax
+0x0f 0x20 0xd8
+
+# CHECKX: movl %cr4, %eax
+0x0f 0x20 0xe0
+
+# CHECKX: movl %dr0, %eax
+0x0f 0x21 0xc0
+
+# CHECKX: movl %dr1, %eax
+0x0f 0x21 0xc8
+
+# CHECKX: movl %dr1, %eax
+0x0f 0x21 0xc8
+
+# CHECKX: movl %dr2, %eax
+0x0f 0x21 0xd0
+
+# CHECKX: movl %dr3, %eax
+0x0f 0x21 0xd8
+
+# CHECKX: movl %dr4, %eax
+0x0f 0x21 0xe0
+
+# CHECKX: movl %dr5, %eax
+0x0f 0x21 0xe8
+
+# CHECKX: movl %dr6, %eax
+0x0f 0x21 0xf0
+
+# CHECKX: movl %dr7, %eax
+0x0f 0x21 0xf8
+
+# CHECK: wait
+0x9b
+
+# CHECK: movl %gs:124, %eax
+0x65 0x66 0x8b 0x06 0x7c 0x00
+
+# CHECK: pushaw
+0x60
+
+# CHECK: popaw
+0x61
+
+# CHECK: pushaw
+0x60
+
+# CHECK: popaw
+0x61
+
+# CHECK: pushal
+0x66 0x60
+
+# CHECK: popal
+0x66 0x61
+
+# CHECK: jmpw *8(%eax)
+0x67 0xff 0x60 0x08
+
+# CHECK: jmpl *8(%eax)
+0x67 0x66 0xff 0x60 0x08
+
+# CHECK: lcalll $2, $4660
+0x66 0x9a 0x34 0x12 0x00 0x00 0x02 0x00
+
+# CHECKX: jcxz
+0xe3 0x00
+
+# CHECKX: jecxz
+0x67 0xe3 0x00
+
+# CHECK: iretw
+0xcf
+
+# CHECK: iretw
+0xcf
+
+# CHECK: iretl
+0x66 0xcf
+
+# CHECK: sysretl
+0x0f 0x07
+
+# CHECK: sysretl
+0x0f 0x07
+
+# CHECK: testl -24(%ebp), %ecx
+0x67 0x66 0x85 0x4d 0xe8
+
+# CHECK: testl -24(%ebp), %ecx
+0x67 0x66 0x85 0x4d 0xe8
+
+# CHECK: pushw %cs
+0x0e
+
+# CHECK: pushw %ds
+0x1e
+
+# CHECK: pushw %ss
+0x16
+
+# CHECK: pushw %es
+0x06
+
+# CHECK: pushw %fs
+0x0f 0xa0
+
+# CHECK: pushw %gs
+0x0f 0xa8
+
+# CHECK: pushw %cs
+0x0e
+
+# CHECK: pushw %ds
+0x1e
+
+# CHECK: pushw %ss
+0x16
+
+# CHECK: pushw %es
+0x06
+
+# CHECK: pushw %fs
+0x0f 0xa0
+
+# CHECK: pushw %gs
+0x0f 0xa8
+
+# CHECK: pushl %cs
+0x66 0x0e
+
+# CHECK: pushl %ds
+0x66 0x1e
+
+# CHECK: pushl %ss
+0x66 0x16
+
+# CHECK: pushl %es
+0x66 0x06
+
+# CHECK: pushl %fs
+0x66 0x0f 0xa0
+
+# CHECK: pushl %gs
+0x66 0x0f 0xa8
+
+# CHECK: popw %ss
+0x17
+
+# CHECK: popw %ds
+0x1f
+
+# CHECK: popw %es
+0x07
+
+# CHECK: popl %ss
+0x66 0x17
+
+# CHECK: popl %ds
+0x66 0x1f
+
+# CHECK: popl %es
+0x66 0x07
+
+# CHECK: pushfl
+0x66 0x9c
+
+# CHECK: popfl
+0x66 0x9d
+
+# CHECK: pushfl
+0x66 0x9c
+
+# CHECK: popfl
+0x66 0x9d
+
+# CHECK: setb %bl
+0x0f 0x92 0xc3
+
+# CHECK: setb %bl
+0x0f 0x92 0xc3
+
+# CHECK: setae %bl
+0x0f 0x93 0xc3
+
+# CHECK: setae %bl
+0x0f 0x93 0xc3
+
+# CHECK: setbe %bl
+0x0f 0x96 0xc3
+
+# CHECK: seta %bl
+0x0f 0x97 0xc3
+
+# CHECK: setp %bl
+0x0f 0x9a 0xc3
+
+# CHECK: setnp %bl
+0x0f 0x9b 0xc3
+
+# CHECK: setl %bl
+0x0f 0x9c 0xc3
+
+# CHECK: setge %bl
+0x0f 0x9d 0xc3
+
+# CHECK: setle %bl
+0x0f 0x9e 0xc3
+
+# CHECK: setg %bl
+0x0f 0x9f 0xc3
+
+# CHECK: setne %cl
+0x0f 0x95 0xc1
+
+# CHECK: setb %bl
+0x0f 0x92 0xc3
+
+# CHECK: setb %bl
+0x0f 0x92 0xc3
+
+# CHECK: lcalll $31438, $31438
+0x66 0x9a 0xce 0x7a 0x00 0x00 0xce 0x7a
+
+# CHECK: lcalll $31438, $31438
+0x66 0x9a 0xce 0x7a 0x00 0x00 0xce 0x7a
+
+# CHECK: ljmpl $31438, $31438
+0x66 0xea 0xce 0x7a 0x00 0x00 0xce 0x7a
+
+# CHECK: ljmpl $31438, $31438
+0x66 0xea 0xce 0x7a 0x00 0x00 0xce 0x7a
+
+# CHECK: lcallw $31438, $31438
+0x9a 0xce 0x7a 0xce 0x7a
+
+# CHECK: lcallw $31438, $31438
+0x9a 0xce 0x7a 0xce 0x7a
+
+# CHECK: ljmpw $31438, $31438
+0xea 0xce 0x7a 0xce 0x7a
+
+# CHECK: ljmpw $31438, $31438
+0xea 0xce 0x7a 0xce 0x7a
+
+# CHECK: lcallw $31438, $31438
+0x9a 0xce 0x7a 0xce 0x7a
+
+# CHECK: lcallw $31438, $31438
+0x9a 0xce 0x7a 0xce 0x7a
+
+# CHECK: ljmpw $31438, $31438
+0xea 0xce 0x7a 0xce 0x7a
+
+# CHECK: ljmpw $31438, $31438
+0xea 0xce 0x7a 0xce 0x7a
+
+# CHECK: calll 
+0x66 0xe8 0x00 0x00 0x00 0x00
+
+# CHECKX: callw
+#0xe8 0x00 0x00
+
+# CHECK: incb %al
+0xfe 0xc0
+
+# CHECK: incw %ax
+0x40
+
+# CHECK: incl %eax
+0x66 0x40
+
+# CHECK: decb %al
+0xfe 0xc8
+
+# CHECK: decw %ax
+0x48
+
+# CHECK: decl %eax
+0x66 0x48
+
+# CHECK: pshufw $14, %mm4, %mm0
+0x0f 0x70 0xc4 0x0e
+
+# CHECK: pshufw $90, %mm4, %mm0
+0x0f 0x70 0xc4 0x5a
+
+# CHECK: aaa
+0x37
+
+# CHECK: aad $1
+0xd5 0x01
+
+# CHECK: aad
+0xd5 0x0a
+
+# CHECK: aad
+0xd5 0x0a
+
+# CHECK: aam $2
+0xd4 0x02
+
+# CHECK: aam
+0xd4 0x0a
+
+# CHECK: aam
+0xd4 0x0a
+
+# CHECK: aas
+0x3f
+
+# CHECK: daa
+0x27
+
+# CHECK: das
+0x2f
+
+# CHECK: retw $31438
+0xc2 0xce 0x7a
+
+# CHECK: lretw $31438
+0xca 0xce 0x7a
+
+# CHECK: retw $31438
+0xc2 0xce 0x7a
+
+# CHECK: lretw $31438
+0xca 0xce 0x7a
+
+# CHECK: retl $31438
+0x66 0xc2 0xce 0x7a
+
+# CHECK: lretl $31438
+0x66 0xca 0xce 0x7a
+
+# CHECK: bound 2(%eax), %bx
+0x67 0x62 0x58 0x02
+
+# CHECK: bound 4(%ebx), %ecx
+0x67 0x66 0x62 0x4b 0x04
+
+# CHECK: arpl %bx, %bx
+0x63 0xdb
+
+# CHECK: arpl %bx, 6(%ecx)
+0x67 0x63 0x59 0x06
+
+# CHECK: lgdtw 4(%eax)
+0x67 0x0f 0x01 0x50 0x04
+
+# CHECK: lgdtw 4(%eax)
+0x67 0x0f 0x01 0x50 0x04
+
+# CHECK: lgdtl 4(%eax)
+0x67 0x66 0x0f 0x01 0x50 0x04
+
+# CHECK: lidtw 4(%eax)
+0x67 0x0f 0x01 0x58 0x04
+
+# CHECK: lidtw 4(%eax)
+0x67 0x0f 0x01 0x58 0x04
+
+# CHECK: lidtl 4(%eax)
+0x67 0x66 0x0f 0x01 0x58 0x04
+
+# CHECK: sgdtw 4(%eax)
+0x67 0x0f 0x01 0x40 0x04
+
+# CHECK: sgdtw 4(%eax)
+0x67 0x0f 0x01 0x40 0x04
+
+# CHECK: sgdtl 4(%eax)
+0x67 0x66 0x0f 0x01 0x40 0x04
+
+# CHECK: sidtw 4(%eax)
+0x67 0x0f 0x01 0x48 0x04
+
+# CHECK: sidtw 4(%eax)
+0x67 0x0f 0x01 0x48 0x04
+
+# CHECK: sidtl 4(%eax)
+0x67 0x66 0x0f 0x01 0x48 0x04
+
+# CHECK: fcompi %st(2)
+0xdf 0xf2
+
+# CHECK: fcompi %st(2)
+0xdf 0xf2
+
+# CHECK: fcompi %st(1)
+0xdf 0xf1
+
+# CHECK: fucompi %st(2)
+0xdf 0xea
+
+# CHECK: fucompi %st(2)
+0xdf 0xea
+
+# CHECK: fucompi %st(1)
+0xdf 0xe9
+
+# CHECK: fldcw 32493
+0xd9 0x2e 0xed 0x7e
+
+# CHECK: fldcw 32493
+0xd9 0x2e 0xed 0x7e
+
+# CHECK: fnstcw 32493
+0xd9 0x3e 0xed 0x7e
+
+# CHECK: fnstcw 32493
+0xd9 0x3e 0xed 0x7e
+
+# CHECK: wait
+0x9b
+
+# CHECK: fnstcw 32493
+0xd9 0x3e 0xed 0x7e
+
+# CHECK: wait
+0x9b
+
+# CHECK: fnstcw 32493
+0xd9 0x3e 0xed 0x7e
+
+# CHECK: fnstsw 32493
+0xdd 0x3e 0xed 0x7e
+
+# CHECK: fnstsw 32493
+0xdd 0x3e 0xed 0x7e
+
+# CHECK: wait
+0x9b
+
+# CHECK: fnstsw 32493
+0xdd 0x3e 0xed 0x7e
+
+# CHECK: wait
+0x9b
+
+# CHECK: fnstsw 32493
+0xdd 0x3e 0xed 0x7e
+
+# CHECK: verr 32493
+0x0f 0x00 0x26 0xed 0x7e
+
+# CHECK: verr 32493
+0x0f 0x00 0x26 0xed 0x7e
+
+# CHECK: wait
+0x9b
+
+# CHECK: fnclex
+0xdb 0xe2
+
+# CHECK: fnclex
+0xdb 0xe2
+
+# CHECK: ud2
+0x0f 0x0b
+
+# CHECK: ud2
+0x0f 0x0b
+
+# CHECK: ud2b
+0x0f 0xb9
+
+# CHECK: loope
+0xe1 0x00
+
+# CHECK: loopne
+0xe0 0x00
+
+# CHECK: outsb
+0x6e
+
+# CHECKX: outsw
+0x6f
+
+# CHECKX: outsl
+0x66 0x6f
+
+# CHECK: insb
+0x6c
+
+# CHECK: insw
+0x6d
+
+# CHECK: insl
+0x66 0x6d
+
+# CHECK: movsb
+0xa4
+
+# CHECKX: movsw
+0xa5
+
+# CHECKX: movsl
+0x66 0xa5
+
+# CHECKX: lodsb
+0xac
+
+# CHECKX: lodsw
+0xad
+
+# CHECKX: lodsl
+0x66 0xad
+
+# CHECK: stosb
+0xaa
+
+# CHECKX: stosw
+0xab
+
+# CHECKX: stosl
+0x66 0xab
+
+# CHECK: strw %ax
+0x0f 0x00 0xc8
+
+# CHECK: strl %eax
+0x66 0x0f 0x00 0xc8
+
+# CHECK: fsubp %st(1)
+0xde 0xe1
+
+# CHECK: fsubp %st(2)
+0xde 0xe2
+
+# CHECKX: nop
+0x66 0x90
+
+# CHECKX: nop
+0x90
+
+# CHECK: xchgl %ecx, %eax
+0x66 0x91
+
+# CHECK: xchgl %ecx, %eax
+0x66 0x91
+
+# CHECK: retw
+0xc3
+
+# CHECK: retl
+0x66 0xc3
+
+# CHECK: lretw
+0xcb
+
+# CHECK: lretl
+0x66 0xcb
+





More information about the llvm-commits mailing list