aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/testsuite/ChangeLog16
-rw-r--r--gas/testsuite/gas/i386/katmai.d3
-rw-r--r--gas/testsuite/gas/i386/long-1-intel.d4
-rw-r--r--gas/testsuite/gas/i386/long-1.d4
-rw-r--r--gas/testsuite/gas/i386/long-1.s4
-rw-r--r--gas/testsuite/gas/i386/prefix.d63
-rw-r--r--gas/testsuite/gas/i386/prefix.s352
-rw-r--r--gas/testsuite/gas/i386/x86-64-long-1-intel.d4
-rw-r--r--gas/testsuite/gas/i386/x86-64-long-1.d4
-rw-r--r--gas/testsuite/gas/i386/x86-64-long-1.s4
-rw-r--r--opcodes/ChangeLog26
-rw-r--r--opcodes/i386-dis.c249
12 files changed, 598 insertions, 135 deletions
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 928adc4..8a92fe9 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+2014-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/16893
+ * gas/i386/katmai.d: Expect "gs" as prefix.
+
+ * gas/i386/long-1.s: Replace movapd with movss.
+ * gas/i386/x86-64-long-1.s: Likewise.
+ * gas/i386/long-1-intel.d: Updated.
+ * gas/i386/long-1.d: Likewise.
+ * gas/i386/x86-64-long-1-intel.d: Likewise.
+ * gas/i386/x86-64-long-1.d: Likewise.
+
+ * gas/i386/prefix.s: Add tests for multiple 0x66, 0x67, 0xf0,
+ 0xf2 and 0xf3 prefixes.
+ * gas/i386/prefix.d: Updated.
+
2014-05-02 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/opcode-intel.d: Undo the last change.
diff --git a/gas/testsuite/gas/i386/katmai.d b/gas/testsuite/gas/i386/katmai.d
index a1c6b97..50e573f 100644
--- a/gas/testsuite/gas/i386/katmai.d
+++ b/gas/testsuite/gas/i386/katmai.d
@@ -160,7 +160,6 @@ Disassembly of section .text:
237: 0f 18 0c 98 [ ]*prefetcht0 \(%eax,%ebx,4\)
23b: 0f 18 12 [ ]*prefetcht1 \(%edx\)
23e: 0f 18 19 [ ]*prefetcht2 \(%ecx\)
- 241: 65 [ ]*gs
- 242: 0f ae[ ]*\(bad\).*
+ 241: 65 0f ae[ ]*gs \(bad\).*
244: ff 00 [ ]*incl \(%eax\)
#pass
diff --git a/gas/testsuite/gas/i386/long-1-intel.d b/gas/testsuite/gas/i386/long-1-intel.d
index 7a73462..2e52136 100644
--- a/gas/testsuite/gas/i386/long-1-intel.d
+++ b/gas/testsuite/gas/i386/long-1-intel.d
@@ -8,7 +8,7 @@
Disassembly of section .text:
0+ <foo>:
-[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 66 0f 28 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
+[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 f3 0f 10 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
[ ]*[a-f0-9]+: 00 f2 add dl,dh
-[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 66 0f 28 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movapd xmm0,XMMWORD PTR \[eax\]
+[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 f3 0f 10 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movss xmm0,DWORD PTR \[eax\]
#pass
diff --git a/gas/testsuite/gas/i386/long-1.d b/gas/testsuite/gas/i386/long-1.d
index 1dccd36..a8cd073 100644
--- a/gas/testsuite/gas/i386/long-1.d
+++ b/gas/testsuite/gas/i386/long-1.d
@@ -7,7 +7,7 @@
Disassembly of section .text:
0+ <foo>:
-[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 66 0f 28 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
+[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 f3 0f 10 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
[ ]*[a-f0-9]+: 00 f2 add %dh,%dl
-[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 66 0f 28 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movapd \(%eax\),%xmm0
+[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 f3 0f 10 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movss \(%eax\),%xmm0
#pass
diff --git a/gas/testsuite/gas/i386/long-1.s b/gas/testsuite/gas/i386/long-1.s
index 4551068..b7e509d 100644
--- a/gas/testsuite/gas/i386/long-1.s
+++ b/gas/testsuite/gas/i386/long-1.s
@@ -14,7 +14,7 @@ foo:
.byte 0xf2
.byte 0xf0
.byte 0xf0
-movapd (%eax), %xmm0
+movss (%eax), %xmm0
.byte 0xf2
.byte 0xf0
.byte 0xf0
@@ -27,4 +27,4 @@ movapd (%eax), %xmm0
.byte 0xf0
.byte 0xf0
.byte 0xf0
-movapd (%eax), %xmm0
+movss (%eax), %xmm0
diff --git a/gas/testsuite/gas/i386/prefix.d b/gas/testsuite/gas/i386/prefix.d
index 4139658..d9f0ae2 100644
--- a/gas/testsuite/gas/i386/prefix.d
+++ b/gas/testsuite/gas/i386/prefix.d
@@ -5,11 +5,60 @@
Disassembly of section .text:
-0+000 <foo>:
- 0: 9b 26 67 d9 3c[ ]+fstcw[ ]+%es:\(%si\)
- 5: 9b df e0 [ ]*fstsw %ax
- 8: 9b df e0 [ ]*fstsw %ax
- b: 9b 67 df e0 [ ]*addr16 fstsw %ax
- f: 36 67 66 f3 a7 [ ]*repz cmpsw %es:\(%di\),%ss:\(%si\)
- 14: 26 9b[ ]*es fwait
+0+ <foo>:
+[ ]*[a-f0-9]+: 9b 26 67 d9 3c fstcw %es:\(%si\)
+[ ]*[a-f0-9]+: 9b df e0 fstsw %ax
+[ ]*[a-f0-9]+: 9b df e0 fstsw %ax
+[ ]*[a-f0-9]+: 9b 67 df e0 addr16 fstsw %ax
+[ ]*[a-f0-9]+: 36 67 66 f3 a7 repz cmpsw %es:\(%di\),%ss:\(%si\)
+[ ]*[a-f0-9]+: 26 9b es fwait
+[ ]*[a-f0-9]+: 66 f2 0f 38 17 data16 \(bad\)
+[ ]*[a-f0-9]+: f2 66 0f 54 repnz \(bad\)
+[ ]*[a-f0-9]+: f2 0f 54 repnz \(bad\)
+[ ]*[a-f0-9]+: f2 66 0f 11 22 data16 movsd %xmm4,\(%edx\)
+[ ]*[a-f0-9]+: f2 67 66 0f 11 22 data16 movsd %xmm4,\(%bp,%si\)
+[ ]*[a-f0-9]+: f2 67 f0 66 0f 11 22 lock data16 movsd %xmm4,\(%bp,%si\)
+[ ]*[a-f0-9]+: f3 66 0f 11 22 data16 movss %xmm4,\(%edx\)
+[ ]*[a-f0-9]+: f3 67 f0 66 0f 11 22 lock data16 movss %xmm4,\(%bp,%si\)
+[ ]*[a-f0-9]+: f3 67 f2 66 0f 11 22 repz data16 movsd %xmm4,\(%bp,%si\)
+[ ]*[a-f0-9]+: f3 66 3e 0f 11 22 data16 movss %xmm4,%ds:\(%edx\)
+[ ]*[a-f0-9]+: f2 66 36 0f 11 22 data16 movsd %xmm4,%ss:\(%edx\)
+[ ]*[a-f0-9]+: f3 f0 f2 66 36 0f 11 22 repz lock data16 movsd %xmm4,%ss:\(%edx\)
+[ ]*[a-f0-9]+: f2 66 3e 36 0f 11 22 data16 ds movsd %xmm4,%ss:\(%edx\)
+[ ]*[a-f0-9]+: f2 67 66 3e 36 0f 11 22 data16 ds movsd %xmm4,%ss:\(%bp,%si\)
+[ ]*[a-f0-9]+: f2 67 f0 66 3e 36 0f 11 22 lock data16 ds movsd %xmm4,%ss:\(%bp,%si\)
+[ ]*[a-f0-9]+: f3 66 3e 36 0f 11 22 data16 ds movss %xmm4,%ss:\(%edx\)
+[ ]*[a-f0-9]+: f3 f0 66 3e 36 0f 11 22 lock data16 ds movss %xmm4,%ss:\(%edx\)
+[ ]*[a-f0-9]+: f3 67 f2 66 3e 36 0f 11 22 repz data16 ds movsd %xmm4,%ss:\(%bp,%si\)
+[ ]*[a-f0-9]+: f2 66 90 repnz xchg %ax,%ax
+[ ]*[a-f0-9]+: f2 67 66 90 repnz addr16 xchg %ax,%ax
+[ ]*[a-f0-9]+: f2 67 f0 66 90 repnz addr16 lock xchg %ax,%ax
+[ ]*[a-f0-9]+: f3 66 90 data16 pause
+[ ]*[a-f0-9]+: f3 67 f0 66 90 addr16 lock data16 pause
+[ ]*[a-f0-9]+: f3 67 f2 66 90 repz addr16 repnz xchg %ax,%ax
+[ ]*[a-f0-9]+: f2 3e 90 repnz ds nop
+[ ]*[a-f0-9]+: f2 f0 67 3e 90 repnz lock addr16 ds nop
+[ ]*[a-f0-9]+: f3 3e 90 ds pause
+[ ]*[a-f0-9]+: f3 66 3e 90 data16 ds pause
+[ ]*[a-f0-9]+: f3 f0 3e 90 lock ds pause
+[ ]*[a-f0-9]+: f3 f0 67 3e 90 lock addr16 ds pause
+[ ]*[a-f0-9]+: f3 f2 67 3e 90 repz repnz addr16 ds nop
+[ ]*[a-f0-9]+: 66 f0 36 90 lock ss xchg %ax,%ax
+[ ]*[a-f0-9]+: f2 36 90 repnz ss nop
+[ ]*[a-f0-9]+: f2 66 36 90 repnz ss xchg %ax,%ax
+[ ]*[a-f0-9]+: f2 f0 36 90 repnz lock ss nop
+[ ]*[a-f0-9]+: f2 f0 67 36 90 repnz lock addr16 ss nop
+[ ]*[a-f0-9]+: f3 36 90 ss pause
+[ ]*[a-f0-9]+: f3 67 36 90 addr16 ss pause
+[ ]*[a-f0-9]+: f3 f0 67 36 90 lock addr16 ss pause
+[ ]*[a-f0-9]+: f3 f2 36 90 repz repnz ss nop
+[ ]*[a-f0-9]+: f3 f2 67 36 90 repz repnz addr16 ss nop
+[ ]*[a-f0-9]+: f3 f0 f2 66 36 90 repz lock repnz ss xchg %ax,%ax
+[ ]*[a-f0-9]+: 66 3e 36 90 ds ss xchg %ax,%ax
+[ ]*[a-f0-9]+: 67 66 3e 36 90 addr16 ds ss xchg %ax,%ax
+[ ]*[a-f0-9]+: 67 f0 66 3e 36 90 addr16 lock ds ss xchg %ax,%ax
+[ ]*[a-f0-9]+: f3 66 3e 36 90 data16 ds ss pause
+[ ]*[a-f0-9]+: f3 f0 66 3e 36 90 lock data16 ds ss pause
+[ ]*[a-f0-9]+: f3 f2 67 3e 36 90 repz repnz addr16 ds ss nop
+[ ]*[a-f0-9]+: f3 67 f2 66 3e 36 90 repz addr16 repnz ds ss xchg %ax,%ax
#pass
diff --git a/gas/testsuite/gas/i386/prefix.s b/gas/testsuite/gas/i386/prefix.s
index 2bf3c71..07020ea 100644
--- a/gas/testsuite/gas/i386/prefix.s
+++ b/gas/testsuite/gas/i386/prefix.s
@@ -4,5 +4,357 @@
es fwait
+ .byte 0x66
+ .byte 0xf2
+ .byte 0x0f
+ .byte 0x38
+ .byte 0x17
+
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x54
+
+ .byte 0xf2
+ .byte 0x0f
+ .byte 0x54
+
+# data16 movsd %xmm4,(%edx)
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 movsd %xmm4,(%bp,%si)
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# lock data16 movsd %xmm4,(%bp,%si)
+ .byte 0xf2
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 movss %xmm4,(%edx)
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# lock data16 movss %xmm4,(%bp,%si)
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# repz data16 movsd %xmm4,(%bp,%si)
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 movss %xmm4,%ds:(%edx)
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 movsd %xmm4,%ss:(%edx)
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# repz lock data16 movsd %xmm4,%ss:(%edx)
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 ds movsd %xmm4,%ss:(%edx)
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 ds movsd %xmm4,%ss:(%bp,%si)
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# lock data16 ds movsd %xmm4,%ss:(%bp,%si)
+ .byte 0xf2
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# data16 ds movss %xmm4,%ss:(%edx)
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# lock data16 ds movss %xmm4,%ss:(%edx)
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# repz data16 ds movsd %xmm4,%ss:(%bp,%si)
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x0f
+ .byte 0x11
+ .byte 0x22
+
+# repnz; xchg %ax,%ax
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x90
+
+# repnz; addr16 xchg %ax,%ax
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x66
+ .byte 0x90
+
+# repnz; addr16 lock xchg %ax,%ax
+ .byte 0xf2
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x90
+
+# data16 pause
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x90
+
+# addr16 lock data16 pause
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x90
+
+# repz; addr16; repnz; xchg %ax,%ax
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x90
+
+# repnz; ds nop
+ .byte 0xf2
+ .byte 0x3e
+ .byte 0x90
+
+# repnz; lock addr16 ds nop
+ .byte 0xf2
+ .byte 0xf0
+ .byte 0x67
+ .byte 0x3e
+ .byte 0x90
+
+# ds pause
+ .byte 0xf3
+ .byte 0x3e
+ .byte 0x90
+
+# data16 ds pause
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x90
+
+# lock ds pause
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0x3e
+ .byte 0x90
+
+# lock addr16 ds pause
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0x67
+ .byte 0x3e
+ .byte 0x90
+
+# repz; repnz; addr16 ds nop
+ .byte 0xf3
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x3e
+ .byte 0x90
+
+# lock ss xchg %ax,%ax
+ .byte 0x66
+ .byte 0xf0
+ .byte 0x36
+ .byte 0x90
+
+# repnz; ss nop
+ .byte 0xf2
+ .byte 0x36
+ .byte 0x90
+
+# repnz; ss xchg %ax,%ax
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x36
+ .byte 0x90
+
+# repnz; lock ss nop
+ .byte 0xf2
+ .byte 0xf0
+ .byte 0x36
+ .byte 0x90
+
+# repnz; lock addr16 ss nop
+ .byte 0xf2
+ .byte 0xf0
+ .byte 0x67
+ .byte 0x36
+ .byte 0x90
+
+# ss pause
+ .byte 0xf3
+ .byte 0x36
+ .byte 0x90
+
+# addr16 ss pause
+ .byte 0xf3
+ .byte 0x67
+ .byte 0x36
+ .byte 0x90
+
+# lock addr16 ss pause
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0x67
+ .byte 0x36
+ .byte 0x90
+
+# repz; repnz; ss nop
+ .byte 0xf3
+ .byte 0xf2
+ .byte 0x36
+ .byte 0x90
+
+# repz; repnz; addr16 ss nop
+ .byte 0xf3
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x36
+ .byte 0x90
+
+# repz; lock; repnz; ss xchg %ax,%ax
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x36
+ .byte 0x90
+
+# ds ss xchg %ax,%ax
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# addr16 ds ss xchg %ax,%ax
+ .byte 0x67
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# addr16 lock ds ss xchg %ax,%ax
+ .byte 0x67
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# data16 ds ss pause
+ .byte 0xf3
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# lock data16 ds ss pause
+ .byte 0xf3
+ .byte 0xf0
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# repz; repnz; addr16 ds ss nop
+ .byte 0xf3
+ .byte 0xf2
+ .byte 0x67
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
+# repz; addr16; repnz; ds ss xchg %ax,%ax
+ .byte 0xf3
+ .byte 0x67
+ .byte 0xf2
+ .byte 0x66
+ .byte 0x3e
+ .byte 0x36
+ .byte 0x90
+
# Get a good alignment.
.p2align 4,0
diff --git a/gas/testsuite/gas/i386/x86-64-long-1-intel.d b/gas/testsuite/gas/i386/x86-64-long-1-intel.d
index 28b291a..0ced3f0 100644
--- a/gas/testsuite/gas/i386/x86-64-long-1-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-long-1-intel.d
@@ -8,7 +8,7 @@
Disassembly of section .text:
0+ <foo>:
-[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 66 0f 28 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
+[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 f3 0f 10 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
[ ]*[a-f0-9]+: 00 f2 add dl,dh
-[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 66 0f 28 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movapd xmm0,XMMWORD PTR \[rax\]
+[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 f3 0f 10 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movss xmm0,DWORD PTR \[rax\]
#pass
diff --git a/gas/testsuite/gas/i386/x86-64-long-1.d b/gas/testsuite/gas/i386/x86-64-long-1.d
index dbb603a..20be6f4 100644
--- a/gas/testsuite/gas/i386/x86-64-long-1.d
+++ b/gas/testsuite/gas/i386/x86-64-long-1.d
@@ -7,7 +7,7 @@
Disassembly of section .text:
0+ <foo>:
-[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 66 0f 28 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
+[ ]*[a-f0-9]+: f2 f0 f0 f0 f2 f2 f2 f2 f2 f2 f0 f0 f3 0f 10 repnz lock lock lock repnz repnz repnz repnz repnz repnz lock lock \(bad\)
[ ]*[a-f0-9]+: 00 f2 add %dh,%dl
-[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 66 0f 28 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movapd \(%rax\),%xmm0
+[ ]*[a-f0-9]+: f0 f0 f0 f2 f2 f2 f2 f0 f0 f0 f0 f3 0f 10 00 lock lock lock repnz repnz repnz repnz lock lock lock lock movss \(%rax\),%xmm0
#pass
diff --git a/gas/testsuite/gas/i386/x86-64-long-1.s b/gas/testsuite/gas/i386/x86-64-long-1.s
index 73f9a53..2b91242 100644
--- a/gas/testsuite/gas/i386/x86-64-long-1.s
+++ b/gas/testsuite/gas/i386/x86-64-long-1.s
@@ -14,7 +14,7 @@ foo:
.byte 0xf2
.byte 0xf0
.byte 0xf0
-movapd (%rax), %xmm0
+movss (%rax), %xmm0
.byte 0xf2
.byte 0xf0
.byte 0xf0
@@ -27,4 +27,4 @@ movapd (%rax), %xmm0
.byte 0xf0
.byte 0xf0
.byte 0xf0
-movapd (%rax), %xmm0
+movss (%rax), %xmm0
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 2e4affe..47555e6 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,29 @@
+2014-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/16893
+ * i386-dis.c (twobyte_has_mandatory_prefix): New variable.
+ (end_codep): Likewise.
+ (mandatory_prefix): Likewise.
+ (active_seg_prefix): Likewise.
+ (ckprefix): Set active_seg_prefix to the active segment register
+ prefix.
+ (seg_prefix): Removed.
+ (get_valid_dis386): Use the last of PREFIX_REPNZ and PREFIX_REPZ
+ for prefix index. Ignore the index if it is invalid and the
+ mandatory prefix isn't required.
+ (print_insn): Set mandatory_prefix if the PREFIX_XXX prefix is
+ mandatory. Don't set PREFIX_REPZ/PREFIX_REPNZ/PREFIX_LOCK bits
+ in used_prefixes here. Don't print unused prefixes. Check
+ active_seg_prefix for the active segment register prefix.
+ Restore the DFLAG bit in sizeflag if the data size prefix is
+ unused. Check the unused mandatory PREFIX_XXX prefixes
+ (append_seg): Only print the segment register which gets used.
+ (OP_E_memory): Check active_seg_prefix for the segment register
+ prefix.
+ (OP_OFF): Likewise.
+ (OP_OFF64): Likewise.
+ (OP_DSreg): Set active_seg_prefix to PREFIX_DS if it is unset.
+
2014-05-02 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/16886
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 99bb482..0ec27ca 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -2845,6 +2845,29 @@ static const unsigned char twobyte_has_modrm[256] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
+static const unsigned char twobyte_has_mandatory_prefix[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+ /* 10 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
+ /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
+ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
+ /* 70 */ 1,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
+ /* c0 */ 0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
+ /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
+ /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
static char obuf[100];
static char *obufp;
static char *mnemonicendp;
@@ -2852,6 +2875,7 @@ static char scratchbuf[100];
static unsigned char *start_codep;
static unsigned char *insn_codep;
static unsigned char *codep;
+static unsigned char *end_codep;
static int last_lock_prefix;
static int last_repz_prefix;
static int last_repnz_prefix;
@@ -2859,6 +2883,10 @@ static int last_data_prefix;
static int last_addr_prefix;
static int last_rex_prefix;
static int last_seg_prefix;
+/* The PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is mandatory. */
+static int mandatory_prefix;
+/* The active segment register prefix. */
+static int active_seg_prefix;
#define MAX_CODE_LENGTH 15
/* We can up to 14 prefixes since the maximum instruction length is
15bytes. */
@@ -11607,6 +11635,7 @@ ckprefix (void)
last_addr_prefix = -1;
last_rex_prefix = -1;
last_seg_prefix = -1;
+ active_seg_prefix = 0;
for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
all_prefixes[i] = 0;
i = 0;
@@ -11656,26 +11685,32 @@ ckprefix (void)
case 0x2e:
prefixes |= PREFIX_CS;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_CS;
break;
case 0x36:
prefixes |= PREFIX_SS;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_SS;
break;
case 0x3e:
prefixes |= PREFIX_DS;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_DS;
break;
case 0x26:
prefixes |= PREFIX_ES;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_ES;
break;
case 0x64:
prefixes |= PREFIX_FS;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_FS;
break;
case 0x65:
prefixes |= PREFIX_GS;
last_seg_prefix = i;
+ active_seg_prefix = PREFIX_GS;
break;
case 0x66:
prefixes |= PREFIX_DATA;
@@ -11718,28 +11753,6 @@ ckprefix (void)
return 0;
}
-static int
-seg_prefix (int pref)
-{
- switch (pref)
- {
- case 0x2e:
- return PREFIX_CS;
- case 0x36:
- return PREFIX_SS;
- case 0x3e:
- return PREFIX_DS;
- case 0x26:
- return PREFIX_ES;
- case 0x64:
- return PREFIX_FS;
- case 0x65:
- return PREFIX_GS;
- default:
- return 0;
- }
-}
-
/* Return the name of the prefix byte PREF, or NULL if PREF is not a
prefix byte. */
@@ -11961,32 +11974,47 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
}
else
{
+ int last_prefix = -1;
+ int prefix = 0;
vindex = 0;
- used_prefixes |= (prefixes & PREFIX_REPZ);
- if (prefixes & PREFIX_REPZ)
- {
- vindex = 1;
- all_prefixes[last_repz_prefix] = 0;
- }
- else
+ /* We check PREFIX_REPNZ and PREFIX_REPZ before PREFIX_DATA.
+ When there are multiple PREFIX_REPNZ and PREFIX_REPZ, the
+ last one wins. */
+ if ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
{
- /* We should check PREFIX_REPNZ and PREFIX_REPZ before
- PREFIX_DATA. */
- used_prefixes |= (prefixes & PREFIX_REPNZ);
- if (prefixes & PREFIX_REPNZ)
+ if (last_repz_prefix > last_repnz_prefix)
{
- vindex = 3;
- all_prefixes[last_repnz_prefix] = 0;
+ vindex = 1;
+ prefix = PREFIX_REPZ;
+ last_prefix = last_repz_prefix;
}
else
{
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- {
- vindex = 2;
- all_prefixes[last_data_prefix] = 0;
- }
+ vindex = 3;
+ prefix = PREFIX_REPNZ;
+ last_prefix = last_repnz_prefix;
}
+
+ /* Ignore the invalid index if it isn't mandatory. */
+ if (!mandatory_prefix
+ && (prefix_table[dp->op[1].bytemode][vindex].name
+ == NULL)
+ && (prefix_table[dp->op[1].bytemode][vindex].op[0].bytemode
+ == 0))
+ vindex = 0;
+ }
+
+ if (vindex == 0 && (prefixes & PREFIX_DATA) != 0)
+ {
+ vindex = 2;
+ prefix = PREFIX_DATA;
+ last_prefix = last_data_prefix;
+ }
+
+ if (vindex != 0)
+ {
+ used_prefixes |= prefix;
+ all_prefixes[last_prefix] = 0;
}
}
dp = &prefix_table[dp->op[1].bytemode][vindex];
@@ -12001,6 +12029,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
FETCH_DATA (info, codep + 2);
vindex = *codep++;
dp = &three_byte_table[dp->op[1].bytemode][vindex];
+ end_codep = codep;
modrm.mod = (*codep >> 6) & 3;
modrm.reg = (*codep >> 3) & 7;
modrm.rm = *codep & 7;
@@ -12083,6 +12112,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
vindex = *codep++;
dp = &xop_table[vex_table_index][vindex];
+ end_codep = codep;
FETCH_DATA (info, codep + 1);
modrm.mod = (*codep >> 6) & 3;
modrm.reg = (*codep >> 3) & 7;
@@ -12144,6 +12174,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
codep++;
vindex = *codep++;
dp = &vex_table[vex_table_index][vindex];
+ end_codep = codep;
/* There is no MODRM byte for VEX [82|77]. */
if (vindex != 0x77 && vindex != 0x82)
{
@@ -12192,6 +12223,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
codep++;
vindex = *codep++;
dp = &vex_table[dp->op[1].bytemode][vindex];
+ end_codep = codep;
/* There is no MODRM byte for VEX [82|77]. */
if (vindex != 0x77 && vindex != 0x82)
{
@@ -12286,6 +12318,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
codep++;
vindex = *codep++;
dp = &evex_table[vex_table_index][vindex];
+ end_codep = codep;
FETCH_DATA (info, codep + 1);
modrm.mod = (*codep >> 6) & 3;
modrm.reg = (*codep >> 3) & 7;
@@ -12565,22 +12598,17 @@ print_insn (bfd_vma pc, disassemble_info *info)
threebyte = *++codep;
dp = &dis386_twobyte[threebyte];
need_modrm = twobyte_has_modrm[*codep];
+ mandatory_prefix = twobyte_has_mandatory_prefix[*codep];
codep++;
}
else
{
dp = &dis386[*codep];
need_modrm = onebyte_has_modrm[*codep];
+ mandatory_prefix = 0;
codep++;
}
- if ((prefixes & PREFIX_REPZ))
- used_prefixes |= PREFIX_REPZ;
- if ((prefixes & PREFIX_REPNZ))
- used_prefixes |= PREFIX_REPNZ;
- if ((prefixes & PREFIX_LOCK))
- used_prefixes |= PREFIX_LOCK;
-
default_prefixes = 0;
if (prefixes & PREFIX_ADDR)
{
@@ -12615,6 +12643,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
}
}
+ end_codep = codep;
if (need_modrm)
{
FETCH_DATA (info, codep + 1);
@@ -12663,24 +12692,6 @@ print_insn (bfd_vma pc, disassemble_info *info)
}
}
- /* See if any prefixes were not used. If so, print the first one
- separately. If we don't do this, we'll wind up printing an
- instruction stream which does not precisely correspond to the
- bytes we are disassembling. */
- if ((prefixes & ~(used_prefixes | default_prefixes)) != 0)
- {
- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
- if (all_prefixes[i])
- {
- const char *name;
- name = prefix_name (all_prefixes[i], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s", name);
- return 1;
- }
- }
-
/* Check if the REX prefix is used. */
if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0)
all_prefixes[last_rex_prefix] = 0;
@@ -12688,8 +12699,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
/* Check if the SEG prefix is used. */
if ((prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | PREFIX_ES
| PREFIX_FS | PREFIX_GS)) != 0
- && (used_prefixes
- & seg_prefix (all_prefixes[last_seg_prefix])) != 0)
+ && (used_prefixes & active_seg_prefix) != 0)
all_prefixes[last_seg_prefix] = 0;
/* Check if the ADDR prefix is used. */
@@ -12697,10 +12707,15 @@ print_insn (bfd_vma pc, disassemble_info *info)
&& (used_prefixes & PREFIX_ADDR) != 0)
all_prefixes[last_addr_prefix] = 0;
- /* Check if the DATA prefix is used. */
- if ((prefixes & PREFIX_DATA) != 0
- && (used_prefixes & PREFIX_DATA) != 0)
- all_prefixes[last_data_prefix] = 0;
+ /* Check if the DATA prefix is used. Restore the DFLAG bit in
+ sizeflag if the DATA prefix is unused. */
+ if ((prefixes & PREFIX_DATA) != 0)
+ {
+ if ((used_prefixes & PREFIX_DATA) != 0)
+ all_prefixes[last_data_prefix] = 0;
+ else if ((default_prefixes & PREFIX_DATA) == 0)
+ sizeflag ^= DFLAG;
+ }
prefix_length = 0;
for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
@@ -12714,6 +12729,26 @@ print_insn (bfd_vma pc, disassemble_info *info)
(*info->fprintf_func) (info->stream, "%s ", name);
}
+ /* If the mandatory PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is
+ unused, opcode is invalid. Since the PREFIX_DATA prefix may be
+ used by putop and MMX/SSE operand and may be overriden by the
+ PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
+ separately. */
+ if (mandatory_prefix
+ && dp != &bad_opcode
+ && (((prefixes
+ & (PREFIX_REPZ | PREFIX_REPNZ)) != 0
+ && (used_prefixes
+ & (PREFIX_REPZ | PREFIX_REPNZ)) == 0)
+ || ((((prefixes
+ & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
+ == PREFIX_DATA)
+ && (used_prefixes & PREFIX_DATA) == 0))))
+ {
+ (*info->fprintf_func) (info->stream, "(bad)");
+ return end_codep - priv.the_buffer;
+ }
+
/* Check maximum code length. */
if ((codep - start_codep) > MAX_CODE_LENGTH)
{
@@ -13681,35 +13716,33 @@ oappend (const char *s)
static void
append_seg (void)
{
- if (prefixes & PREFIX_CS)
+ /* Only print the active segment register. */
+ if (!active_seg_prefix)
+ return;
+
+ used_prefixes |= active_seg_prefix;
+ switch (active_seg_prefix)
{
- used_prefixes |= PREFIX_CS;
+ case PREFIX_CS:
oappend_maybe_intel ("%cs:");
- }
- if (prefixes & PREFIX_DS)
- {
- used_prefixes |= PREFIX_DS;
+ break;
+ case PREFIX_DS:
oappend_maybe_intel ("%ds:");
- }
- if (prefixes & PREFIX_SS)
- {
- used_prefixes |= PREFIX_SS;
+ break;
+ case PREFIX_SS:
oappend_maybe_intel ("%ss:");
- }
- if (prefixes & PREFIX_ES)
- {
- used_prefixes |= PREFIX_ES;
+ break;
+ case PREFIX_ES:
oappend_maybe_intel ("%es:");
- }
- if (prefixes & PREFIX_FS)
- {
- used_prefixes |= PREFIX_FS;
+ break;
+ case PREFIX_FS:
oappend_maybe_intel ("%fs:");
- }
- if (prefixes & PREFIX_GS)
- {
- used_prefixes |= PREFIX_GS;
+ break;
+ case PREFIX_GS:
oappend_maybe_intel ("%gs:");
+ break;
+ default:
+ break;
}
}
@@ -14541,10 +14574,7 @@ OP_E_memory (int bytemode, int sizeflag)
{
if (modrm.mod != 0 || base == 5)
{
- if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS))
- ;
- else
+ if (!active_seg_prefix)
{
oappend (names_seg[ds_reg - es_reg]);
oappend (":");
@@ -14617,10 +14647,7 @@ OP_E_memory (int bytemode, int sizeflag)
}
else if (intel_syntax)
{
- if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS))
- ;
- else
+ if (!active_seg_prefix)
{
oappend (names_seg[ds_reg - es_reg]);
oappend (":");
@@ -15178,8 +15205,7 @@ OP_OFF (int bytemode, int sizeflag)
if (intel_syntax)
{
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ if (!active_seg_prefix)
{
oappend (names_seg[ds_reg - es_reg]);
oappend (":");
@@ -15209,8 +15235,7 @@ OP_OFF64 (int bytemode, int sizeflag)
if (intel_syntax)
{
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ if (!active_seg_prefix)
{
oappend (names_seg[ds_reg - es_reg]);
oappend (":");
@@ -15286,14 +15311,10 @@ OP_DSreg (int code, int sizeflag)
intel_operand_size (b_mode, sizeflag);
}
}
- if ((prefixes
- & (PREFIX_CS
- | PREFIX_DS
- | PREFIX_SS
- | PREFIX_ES
- | PREFIX_FS
- | PREFIX_GS)) == 0)
- prefixes |= PREFIX_DS;
+ /* Set active_seg_prefix to PREFIX_DS if it is unset so that the
+ default segment register DS is printed. */
+ if (!active_seg_prefix)
+ active_seg_prefix = PREFIX_DS;
append_seg ();
ptr_reg (code, sizeflag);
}