This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] x86-64 opcode corrections
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Thu, 03 Jun 2004 17:35:01 +0200
- Subject: [PATCH] x86-64 opcode corrections
A lot of illegal instructions were accepted by the assembler, and in a
few cases useless rex prefixes would have been generated.
2004-06-03 Jan Beulich <jbeulich@novell.com>
* include/opcode/i386.h: Adjust instructions descriptions to
better
match the specification.
* gas/testsuite/gas/cfi/cfi-x86_64.d: Adjust expectation for
leave to
not have a rex prefix.
* gas/testsuite/gas/i386/x86-64-inval.[ls]: Add a bunch of
instructions
illegal in 64-bit mode.
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/cfi/cfi-x86_64.d 2004-03-07
11:04:42.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/cfi/cfi-x86_64.d 2004-06-03
10:18:27.800724360 +0200
@@ -21,13 +21,13 @@
DW_CFA_advance_loc: 12 to 00000033
DW_CFA_def_cfa_offset: 8
-00000030 0000001c 00000034 FDE cie=00000000 pc=00000038..00000047
+00000030 0000001c 00000034 FDE cie=00000000 pc=00000038..00000046
DW_CFA_advance_loc: 1 to 00000039
DW_CFA_def_cfa_offset: 16
DW_CFA_offset: r6 at cfa-16
DW_CFA_advance_loc: 3 to 0000003c
DW_CFA_def_cfa_reg: r6
- DW_CFA_advance_loc: 10 to 00000046
+ DW_CFA_advance_loc: 9 to 00000045
DW_CFA_def_cfa: r7 ofs 8
DW_CFA_nop
DW_CFA_nop
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-inval.l 2002-03-01
09:10:06.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-inval.l 2004-06-01
13:10:52.000000000 +0200
@@ -11,20 +11,98 @@
.*:12: Error: .*
.*:13: Error: .*
.*:14: Error: .*
+.*:15: Error: .*
+.*:16: Error: .*
+.*:17: Error: .*
+.*:18: Error: .*
+.*:19: Error: .*
+.*:20: Error: .*
+.*:21: Error: .*
+.*:22: Error: .*
+.*:23: Error: .*
+.*:24: Error: .*
+.*:25: Error: .*
+.*:26: Error: .*
+.*:27: Error: .*
+.*:28: Error: .*
+.*:29: Error: .*
+.*:30: Error: .*
+.*:31: Error: .*
+.*:32: Error: .*
+.*:33: Error: .*
+.*:34: Error: .*
+.*:35: Error: .*
+.*:36: Error: .*
+.*:37: Error: .*
+.*:38: Error: .*
+.*:39: Error: .*
+.*:40: Error: .*
+.*:41: Error: .*
+.*:42: Error: .*
+.*:43: Error: .*
+.*:44: Error: .*
+.*:45: Error: .*
+.*:46: Error: .*
+.*:47: Error: .*
+.*:48: Error: .*
+.*:49: Error: .*
+.*:50: Error: .*
+.*:51: Error: .*
+.*:52: Error: .*
+.*:53: Error: .*
GAS LISTING .*
- 1 [ ]* .text
+ 1 [ ]*.text
2 [ ]*# All the following should be illegal for x86-64
- 3 [ ]*calll \*%eax # 32-bit data size not allowed
- 4 [ ]*calll \*\(%ax\) # 32-bit data size not allowed
- 5 [ ]*calll \*\(%eax\) # 32-bit data size not allowed
- 6 [ ]*calll \*\(%r8\) # 32-bit data size not allowed
- 7 [ ]*calll \*\(%rax\) # 32-bit data size not allowed
- 8 [ ]*callq \*\(%ax\) # 32-bit data size not allowed
- 9 [ ]*callw \*\(%ax\) # no 16-bit addressing
- 10 [ ]*foo:[ ]*jcxz foo # No prefix exists to
select CX as a counter
- 11 [ ]*popl %eax # can\'t have 32-bit stack operands
- 12 [ ]*pushl %eax # can\'t have 32-bit stack operands
- 13 [ ]*pushfl # can\'t have 32-bit stack
operands
- 14 [ ]*popfl # can\'t have 32-bit stack operands
+ 3 [ ]*aaa # illegal
+ 4 [ ]*aad # illegal
+ 5 [ ]*aam # illegal
+ 6 [ ]*aas # illegal
+ 7 [ ]*arpl %ax,%ax # illegal
+ 8 [ ]*bound %eax,\(%rax\) # illegal
+ 9 [ ]*calll \*%eax # 32-bit data size not allowed
+ 10 [ ]*calll \*\(%ax\) # 32-bit data size not allowed
+ 11 [ ]*calll \*\(%eax\) # 32-bit data size not allowed
+ 12 [ ]*calll \*\(%r8\) # 32-bit data size not allowed
+ 13 [ ]*calll \*\(%rax\) # 32-bit data size not allowed
+ 14 [ ]*callq \*\(%ax\) # 32-bit data size not allowed
+ 15 [ ]*callw \*\(%ax\) # no 16-bit addressing
+ 16 [ ]*daa # illegal
+ 17 [ ]*das # illegal
+ 18 [ ]*enterl \$0,\$0 # can't have 32-bit stack
operands
+ 19 [ ]*into # illegal
+ 20 [ ]*foo:[ ]*jcxz foo # No prefix exists to
select CX as a counter
+ 21 [ ]*jmpl \*%eax # 32-bit data size not allowed
+ 22 [ ]*jmpl \*\(%rax\) # 32-bit data size not allowed
+ 23 [ ]*lahf # illegal
+ 24 [ ]*lcalll \$0,\$0 # illegal
+ 25 [ ]*lcallq \$0,\$0 # illegal
+ 26 [ ]*ldsl %eax,\(%rax\) # illegal
+ 27 [ ]*ldsq %rax,\(%rax\) # illegal
+ 28 [ ]*lesl %eax,\(%rax\) # illegal
+ 29 [ ]*lesq %rax,\(%rax\) # illegal
+ 30 [ ]*ljmpl \$0,\$0 # illegal
+ 31 [ ]*ljmpq \$0,\$0 # illegal
+ 32 [ ]*ljmpq \*\(%rax\) # 64-bit data size not allowed
+ 33 [ ]*loopw foo # No prefix exists to select CX as a
counter
+ 34 [ ]*loopew foo # No prefix exists to select CX as a
counter
+ 35 [ ]*loopnew foo # No prefix exists to select CX as a
counter
+ 36 [ ]*loopnzw foo # No prefix exists to select CX as a
counter
+ 37 [ ]*loopzw foo # No prefix exists to select CX as a
counter
+ 38 [ ]*leavel # can't have 32-bit stack
operands
+ 39 [ ]*pop %ds # illegal
+ 40 [ ]*pop %es # illegal
+ 41 [ ]*pop %ss # illegal
+ 42 [ ]*popa # illegal
+ 43 [ ]*popl %eax # can't have 32-bit stack operands
+ 44 [ ]*push %cs # illegal
+ 45 [ ]*push %ds # illegal
+ 46 [ ]*push %es # illegal
+ 47 [ ]*push %ss # illegal
+ 48 [ ]*pusha # illegal
+ 49 [ ]*pushl %eax # can't have 32-bit stack operands
+ 50 [ ]*pushfl # can't have 32-bit stack
operands
+ 51 [ ]*popfl # can't have 32-bit stack operands
+ 52 [ ]*retl # can't have 32-bit stack operands
+ 53 [ ]*sahf # illegal
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-inval.s 2002-03-01
09:10:06.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-inval.s 2004-06-01
13:05:40.000000000 +0200
@@ -1,5 +1,11 @@
.text
# All the following should be illegal for x86-64
+ aaa # illegal
+ aad # illegal
+ aam # illegal
+ aas # illegal
+ arpl %ax,%ax # illegal
+ bound %eax,(%rax) # illegal
calll *%eax # 32-bit data size not allowed
calll *(%ax) # 32-bit data size not allowed
calll *(%eax) # 32-bit data size not allowed
@@ -7,8 +13,41 @@
calll *(%rax) # 32-bit data size not allowed
callq *(%ax) # 32-bit data size not allowed
callw *(%ax) # no 16-bit addressing
+ daa # illegal
+ das # illegal
+ enterl $0,$0 # can't have 32-bit stack operands
+ into # illegal
foo: jcxz foo # No prefix exists to select CX as a counter
+ jmpl *%eax # 32-bit data size not allowed
+ jmpl *(%rax) # 32-bit data size not allowed
+ lahf # illegal
+ lcalll $0,$0 # illegal
+ lcallq $0,$0 # illegal
+ ldsl %eax,(%rax) # illegal
+ ldsq %rax,(%rax) # illegal
+ lesl %eax,(%rax) # illegal
+ lesq %rax,(%rax) # illegal
+ ljmpl $0,$0 # illegal
+ ljmpq $0,$0 # illegal
+ ljmpq *(%rax) # 64-bit data size not allowed
+ loopw foo # No prefix exists to select CX as a counter
+ loopew foo # No prefix exists to select CX as a counter
+ loopnew foo # No prefix exists to select CX as a counter
+ loopnzw foo # No prefix exists to select CX as a counter
+ loopzw foo # No prefix exists to select CX as a counter
+ leavel # can't have 32-bit stack operands
+ pop %ds # illegal
+ pop %es # illegal
+ pop %ss # illegal
+ popa # illegal
popl %eax # can't have 32-bit stack operands
+ push %cs # illegal
+ push %ds # illegal
+ push %es # illegal
+ push %ss # illegal
+ pusha # illegal
pushl %eax # can't have 32-bit stack operands
pushfl # can't have 32-bit stack operands
popfl # can't have 32-bit stack operands
+ retl # can't have 32-bit stack operands
+ sahf # illegal
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/include/opcode/i386.h 2004-03-12
14:38:46.000000000 +0100
+++ 2004-06-03.09.12/include/opcode/i386.h 2004-06-03
10:20:39.481705808 +0200
@@ -84,7 +84,8 @@
#define MOV_AX_DISP32 0xa0
/* In the 64bit mode the short form mov immediate is redefined to
have
64bit displacement value. */
-{ "mov", 2, 0xa0, X, CpuNo64,bwlq_Suf|D|W, {
Disp16|Disp32, Acc, 0 } },
+{ "mov", 2, 0xa0, X, CpuNo64,bwl_Suf|D|W, {
Disp16|Disp32, Acc, 0 } },
+/*{ "mov", 2, 0xa0, X, Cpu64,
bwlq_Suf|D|W, { Disp32|Disp64, Acc, 0 }
},*/
{ "mov", 2, 0x88, X, 0, bwlq_Suf|D|W|Modrm, { Reg,
Reg|AnyMem, 0} },
/* In the 64bit mode the short form mov immediate is redefined to
have
64bit displacement value. */
@@ -106,7 +107,7 @@
{ "mov", 2, 0x0f20, X, Cpu64,
q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Control, Reg64|InvMem, 0} },
{ "mov", 2, 0x0f21, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{
Debug, Reg32|InvMem, 0} },
{ "mov", 2, 0x0f21, X, Cpu64,
q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Debug, Reg64|InvMem, 0} },
-{ "mov", 2, 0x0f24, X, Cpu386, l_Suf|D|Modrm|IgnoreSize, { Test,
Reg32|InvMem, 0} },
+{ "mov", 2, 0x0f24, X, Cpu386|CpuNo64,
l_Suf|D|Modrm|IgnoreSize, { Test, Reg32|InvMem, 0} },
{ "movabs",2, 0xa0, X, Cpu64, bwlq_Suf|D|W, {
Disp64, Acc, 0 } },
{ "movabs",2, 0xb0, X, Cpu64, q_Suf|W|ShortForm, { Imm64,
Reg64, 0 } },
@@ -125,9 +126,10 @@
{"movsx", 2, 0x0fbe, X, Cpu64, b_Suf|Modrm|Rex64, {
Reg8|ByteMem, Reg64, 0} },
{"movsx", 2, 0x0fbf, X, Cpu64, w_Suf|Modrm|Rex64, {
Reg16|ShortMem, Reg64, 0} },
{"movsx", 2, 0x63, X, Cpu64, l_Suf|Modrm|Rex64, {
Reg32|WordMem, Reg64, 0} },
+{"movsxd", 2, 0x63, X, Cpu64,
NoSuf|Modrm|IgnoreSize|Rex64, { Reg32|WordMem, Reg64, 0} },
/* Move with zero extend. */
-{"movzb", 2, 0x0fb6, X, Cpu386,
wl_Suf|Modrm, { Reg8|ByteMem, WordReg, 0}
},
+{"movzb", 2, 0x0fb6, X, Cpu386,
wl_Suf|Modrm, { Reg8|ByteMem, Reg16|Reg32,
0} },
{"movzwl", 2, 0x0fb7, X, Cpu386, NoSuf|Modrm, {
Reg16|ShortMem, Reg32, 0} },
/* These instructions are not particulary usefull, since the zero
extend
32->64 is implicit, but we can encode them. */
@@ -138,23 +140,22 @@
{"movzx", 2, 0x0fb7, X, Cpu386, w_Suf|Modrm, {
Reg16|ShortMem, Reg32, 0} },
/* These instructions are not particulary usefull, since the zero
extend
32->64 is implicit, but we can encode them. */
-{"movzx", 2, 0x0fb6, X, Cpu386, b_Suf|Modrm|Rex64, {
Reg8|ByteMem, Reg64, 0} },
-{"movzx", 2, 0x0fb7, X, Cpu386, w_Suf|Modrm|Rex64, {
Reg16|ShortMem, Reg64, 0} },
+{"movzx", 2, 0x0fb6, X, Cpu64, b_Suf|Modrm|Rex64, {
Reg8|ByteMem, Reg64, 0} },
+{"movzx", 2, 0x0fb7, X, Cpu64, w_Suf|Modrm|Rex64, {
Reg16|ShortMem, Reg64, 0} },
/* Push instructions. */
{"push", 1, 0x50, X, CpuNo64, wl_Suf|ShortForm|DefaultSize, {
WordReg, 0, 0 } },
{"push", 1, 0xff, 6, CpuNo64, wl_Suf|Modrm|DefaultSize, {
WordReg|WordMem, 0, 0 } },
{"push", 1, 0x6a, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { Imm8S,
0, 0} },
{"push", 1, 0x68, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, {
Imm16|Imm32, 0, 0} },
-{"push", 1, 0x06, X, 0|CpuNo64, wl_Suf|Seg2ShortForm|DefaultSize, {
SReg2, 0, 0 } },
+{"push", 1, 0x06, X, CpuNo64, wl_Suf|Seg2ShortForm|DefaultSize, {
SReg2, 0, 0 } },
{"push", 1, 0x0fa0, X, Cpu386|CpuNo64,
wl_Suf|Seg3ShortForm|DefaultSize, { SReg3, 0, 0 } },
/* In 64bit mode, the operand size is implicitly 64bit. */
-{"push", 1, 0x50, X, Cpu64, wq_Suf|ShortForm|DefaultSize|NoRex64, {
WordReg, 0, 0 } },
-{"push", 1, 0xff, 6, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64, {
WordReg|WordMem, 0, 0 } },
-{"push", 1, 0x6a, X, Cpu186|Cpu64, wq_Suf|DefaultSize|NoRex64, {
Imm8S, 0, 0} },
-{"push", 1, 0x68, X, Cpu186|Cpu64, wq_Suf|DefaultSize|NoRex64, {
Imm32S|Imm16, 0, 0} },
-{"push", 1, 0x06, X,
Cpu64, wq_Suf|Seg2ShortForm|DefaultSize|NoRex64, { SReg2, 0, 0
} },
-{"push", 1, 0x0fa0, X, Cpu386|Cpu64,
wq_Suf|Seg3ShortForm|DefaultSize|NoRex64, { SReg3, 0, 0 } },
+{"push", 1, 0x50, X, Cpu64, wq_Suf|ShortForm|DefaultSize|NoRex64, {
Reg16|Reg64, 0, 0 } },
+{"push", 1, 0xff, 6, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64, {
Reg16|Reg64|WordMem, 0, 0 } },
+{"push", 1, 0x6a, X, Cpu64, wq_Suf|DefaultSize|NoRex64, { Imm8S, 0,
0} },
+{"push", 1, 0x68, X, Cpu64, wq_Suf|DefaultSize|NoRex64, {
Imm32S|Imm16, 0, 0} },
+{"push", 1, 0x0fa0, X,
Cpu64, wq_Suf|Seg3ShortForm|DefaultSize|NoRex64, { SReg3, 0, 0
} },
{"pusha", 0, 0x60, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { 0, 0,
0 } },
@@ -165,9 +166,8 @@
{"pop", 1, 0x07, X, CpuNo64,
wl_Suf|Seg2ShortForm|DefaultSize, { SReg2, 0, 0 } },
{"pop", 1, 0x0fa1, X, Cpu386|CpuNo64,
wl_Suf|Seg3ShortForm|DefaultSize, { SReg3, 0, 0 } },
/* In 64bit mode, the operand size is implicitly 64bit. */
-{"pop", 1, 0x58, X, Cpu64,
wq_Suf|ShortForm|DefaultSize|NoRex64, { WordReg, 0, 0 } },
-{"pop", 1, 0x8f, 0, Cpu64,
wq_Suf|Modrm|DefaultSize|NoRex64, { WordReg|WordMem, 0, 0 } },
-{"pop", 1, 0x07, X, Cpu64,
wq_Suf|Seg2ShortForm|DefaultSize|NoRex64, { SReg2, 0, 0 } },
+{"pop", 1, 0x58, X, Cpu64,
wq_Suf|ShortForm|DefaultSize|NoRex64, { Reg16|Reg64, 0, 0 } },
+{"pop", 1, 0x8f, 0, Cpu64,
wq_Suf|Modrm|DefaultSize|NoRex64, { Reg16|Reg64|WordMem, 0, 0 }
},
{"pop", 1, 0x0fa1, X, Cpu64,
wq_Suf|Seg3ShortForm|DefaultSize|NoRex64, { SReg3, 0, 0 } },
{"popa", 0, 0x61, X, Cpu186|CpuNo64,
wl_Suf|DefaultSize, { 0, 0, 0 } },
@@ -177,8 +177,18 @@
In the 64bit code, xchg eax, eax is reused for new nop
instruction.
*/
+#if 0 /* While the two entries that are disabled generate shorter
code
+ for xchg eax, reg (on x86_64), the special case xchg eax,
eax
+ does not get handled correctly - it degenerates into nop,
but
+ that way the side effect of zero-extending eax to rax is
lost.*/
{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { WordReg, Acc,
0 } },
{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { Acc, WordReg,
0 } },
+#else
+{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { WordReg, Acc,
0 } },
+{"xchg", 2, 0x90, X, CpuNo64, wl_Suf|ShortForm, { Acc, WordReg,
0 } },
+{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Reg16|Reg64,
Acc, 0 } },
+{"xchg", 2, 0x90, X, Cpu64, wq_Suf|ShortForm, { Acc,
Reg16|Reg64, 0 } },
+#endif
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg,
Reg|AnyMem, 0 } },
{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem,
Reg, 0 } },
@@ -196,11 +206,11 @@
{"lea", 2, 0x8d, X, 0, wlq_Suf|Modrm, {
WordMem, WordReg, 0 } },
/* Load segment registers from memory. */
-{"lds", 2, 0xc5, X, CpuNo64, wlq_Suf|Modrm, {
WordMem, WordReg, 0} },
-{"les", 2, 0xc4, X, CpuNo64, wlq_Suf|Modrm, {
WordMem, WordReg, 0} },
-{"lfs", 2, 0x0fb4, X, Cpu386, wlq_Suf|Modrm, {
WordMem, WordReg, 0} },
-{"lgs", 2, 0x0fb5, X, Cpu386, wlq_Suf|Modrm, {
WordMem, WordReg, 0} },
-{"lss", 2, 0x0fb2, X, Cpu386, wlq_Suf|Modrm, {
WordMem, WordReg, 0} },
+{"lds", 2, 0xc5, X, CpuNo64, wl_Suf|Modrm, { WordMem,
WordReg, 0} },
+{"les", 2, 0xc4, X, CpuNo64, wl_Suf|Modrm, { WordMem,
WordReg, 0} },
+{"lfs", 2, 0x0fb4, X, Cpu386, wl_Suf|Modrm, {
WordMem, WordReg, 0} },
+{"lgs", 2, 0x0fb5, X, Cpu386, wl_Suf|Modrm, {
WordMem, WordReg, 0} },
+{"lss", 2, 0x0fb2, X, Cpu386, wl_Suf|Modrm, {
WordMem, WordReg, 0} },
/* Flags register instructions. */
{"clc", 0, 0xf8, X, 0, NoSuf, { 0, 0,
0} },
@@ -210,9 +220,9 @@
{"cmc", 0, 0xf5, X, 0, NoSuf, { 0, 0,
0} },
{"lahf", 0, 0x9f, X, CpuNo64,NoSuf, { 0, 0, 0} },
{"sahf", 0, 0x9e, X, CpuNo64,NoSuf, { 0, 0, 0} },
-{"pushf", 0, 0x9c, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0, 0} },
+{"pushf", 0, 0x9c, X, CpuNo64,wl_Suf|DefaultSize, { 0, 0, 0} },
{"pushf", 0, 0x9c, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{ 0, 0, 0}
},
-{"popf", 0, 0x9d, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0, 0} },
+{"popf", 0, 0x9d, X, CpuNo64,wl_Suf|DefaultSize, { 0, 0, 0} },
{"popf", 0, 0x9d, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{ 0, 0, 0}
},
{"stc", 0, 0xf9, X, 0, NoSuf, { 0, 0,
0} },
{"std", 0, 0xfd, X, 0, NoSuf, { 0, 0,
0} },
@@ -276,14 +286,14 @@
{"neg", 1, 0xf6, 3, 0, bwlq_Suf|W|Modrm, {
Reg|AnyMem, 0, 0} },
{"not", 1, 0xf6, 2, 0, bwlq_Suf|W|Modrm, {
Reg|AnyMem, 0, 0} },
-{"aaa", 0, 0x37, X, 0, NoSuf, { 0, 0,
0} },
-{"aas", 0, 0x3f, X, 0, NoSuf, { 0, 0,
0} },
-{"daa", 0, 0x27, X, 0, NoSuf, { 0, 0,
0} },
-{"das", 0, 0x2f, X, 0, NoSuf, { 0, 0,
0} },
-{"aad", 0, 0xd50a, X, 0, NoSuf, { 0, 0,
0} },
-{"aad", 1, 0xd5, X, 0, NoSuf, { Imm8S,
0, 0} },
-{"aam", 0, 0xd40a, X, 0, NoSuf, { 0, 0,
0} },
-{"aam", 1, 0xd4, X, 0, NoSuf, { Imm8S,
0, 0} },
+{"aaa", 0, 0x37, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"aas", 0, 0x3f, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"daa", 0, 0x27, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"das", 0, 0x2f, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"aad", 0, 0xd50a, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"aad", 1, 0xd5, X, CpuNo64,
NoSuf, { Imm8S, 0, 0} },
+{"aam", 0, 0xd40a, X, CpuNo64,
NoSuf, { 0, 0, 0} },
+{"aam", 1, 0xd4, X, CpuNo64,
NoSuf, { Imm8S, 0, 0} },
/* Conversion insns. */
/* Intel naming */
@@ -370,37 +380,38 @@
{"shrd", 2, 0x0fad, X, Cpu386, wlq_Suf|Modrm, {
WordReg, WordReg|WordMem, 0} },
/* Control transfer instructions. */
-{"call", 1, 0xe8, X, 0, wlq_Suf|JumpDword|DefaultSize, {
Disp16|Disp32, 0, 0} },
+{"call", 1, 0xe8, X, CpuNo64,
wl_Suf|JumpDword|DefaultSize, { Disp16|Disp32, 0, 0} },
+{"call", 1, 0xe8, X, Cpu64,
wq_Suf|JumpDword|DefaultSize|NoRex64, { Disp32, 0, 0}
},
{"call", 1, 0xff, 2, CpuNo64, wl_Suf|Modrm|DefaultSize, {
WordReg|WordMem|JumpAbsolute, 0, 0} },
-{"call", 1, 0xff, 2, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64,{
WordReg|WordMem|JumpAbsolute, 0, 0} },
+{"call", 1, 0xff, 2, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64,{
Reg64|LLongMem|JumpAbsolute, 0, 0} },
/* Intel Syntax */
-{"call", 2, 0x9a, X, CpuNo64,wlq_Suf|JumpInterSegment|DefaultSize, {
Imm16, Imm16|Imm32, 0} },
+{"call", 2, 0x9a, X, CpuNo64,wl_Suf|JumpInterSegment|DefaultSize, {
Imm16, Imm16|Imm32, 0} },
/* Intel Syntax */
{"call", 1, 0xff, 3, 0, x_Suf|Modrm|DefaultSize, {
WordMem, 0, 0} },
{"lcall", 2, 0x9a, X, CpuNo64,
wl_Suf|JumpInterSegment|DefaultSize, { Imm16, Imm16|Imm32, 0} },
-{"lcall", 1, 0xff, 3, CpuNo64,
wl_Suf|Modrm|DefaultSize, { WordMem|JumpAbsolute, 0, 0} },
-{"lcall", 1, 0xff, 3, Cpu64, q_Suf|Modrm|DefaultSize|NoRex64,{
WordMem|JumpAbsolute, 0, 0} },
+{"lcall", 1, 0xff, 3, 0, wlq_Suf|Modrm|DefaultSize, {
WordMem|JumpAbsolute, 0, 0} },
#define JUMP_PC_RELATIVE 0xeb
{"jmp", 1, 0xeb, X, 0, NoSuf|Jump, { Disp,
0, 0} },
{"jmp", 1, 0xff, 4, CpuNo64, wl_Suf|Modrm, {
WordReg|WordMem|JumpAbsolute, 0, 0} },
-{"jmp", 1, 0xff, 4, Cpu64, wq_Suf|Modrm|NoRex64, {
WordReg|WordMem|JumpAbsolute, 0, 0} },
+{"jmp", 1, 0xff, 4, Cpu64, wq_Suf|Modrm|NoRex64, {
Reg16|Reg64|ShortMem|LLongMem|JumpAbsolute, 0, 0} },
/* Intel Syntax */
{"jmp", 2, 0xea, X, CpuNo64,wl_Suf|JumpInterSegment, { Imm16,
Imm16|Imm32, 0} },
/* Intel Syntax */
{"jmp", 1, 0xff, 5, 0, x_Suf|Modrm, { WordMem, 0, 0}
},
{"ljmp", 2, 0xea, X, CpuNo64, wl_Suf|JumpInterSegment, {
Imm16, Imm16|Imm32, 0} },
-{"ljmp", 1, 0xff, 5, CpuNo64, wl_Suf|Modrm, {
WordMem|JumpAbsolute, 0, 0} },
-{"ljmp", 1, 0xff, 5, Cpu64, q_Suf|Modrm|NoRex64, {
WordMem|JumpAbsolute, 0, 0} },
+{"ljmp", 1, 0xff, 5, 0, wl_Suf|Modrm, {
WordMem|JumpAbsolute, 0, 0} },
-{"ret", 0, 0xc3, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0,
0} },
-{"ret", 1, 0xc2, X, CpuNo64,wlq_Suf|DefaultSize, { Imm16,
0, 0} },
-{"ret", 0, 0xc3, X, Cpu64, q_Suf|DefaultSize|NoRex64,{ 0,
0, 0} },
-{"ret", 1, 0xc2, X, Cpu64, q_Suf|DefaultSize|NoRex64,{
Imm16, 0, 0} },
+{"ret", 0, 0xc3, X, CpuNo64,wl_Suf|DefaultSize, { 0, 0,
0} },
+{"ret", 1, 0xc2, X, CpuNo64,wl_Suf|DefaultSize, { Imm16,
0, 0} },
+{"ret", 0, 0xc3, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{ 0,
0, 0} },
+{"ret", 1, 0xc2, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{
Imm16, 0, 0} },
{"lret", 0, 0xcb, X, 0, wlq_Suf|DefaultSize, { 0, 0, 0} },
{"lret", 1, 0xca, X, 0, wlq_Suf|DefaultSize, { Imm16, 0, 0}
},
-{"enter", 2, 0xc8, X, Cpu186, wlq_Suf|DefaultSize, { Imm16, Imm8,
0} },
-{"leave", 0, 0xc9, X, Cpu186, wlq_Suf|DefaultSize, { 0, 0, 0} },
+{"enter", 2, 0xc8, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { Imm16,
Imm8, 0} },
+{"enter", 2, 0xc8, X, Cpu64, wq_Suf|DefaultSize|NoRex64, { Imm16,
Imm8, 0} },
+{"leave", 0, 0xc9, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { 0, 0,
0} },
+{"leave", 0, 0xc9, X, Cpu64, wq_Suf|DefaultSize|NoRex64, { 0, 0,
0} },
/* Conditional jumps. */
{"jo", 1, 0x70, X, 0, NoSuf|Jump, { Disp,
0, 0} },
@@ -540,29 +551,33 @@
#define INT3_OPCODE 0xcc
{"int", 1, 0xcd, X, 0, NoSuf, { Imm8,
0, 0} },
{"int3", 0, 0xcc, X, 0, NoSuf, { 0, 0, 0} },
-{"into", 0, 0xce, X, 0, NoSuf, { 0, 0, 0} },
+{"into", 0, 0xce, X, CpuNo64, NoSuf, { 0, 0,
0} },
{"iret", 0, 0xcf, X, 0, wlq_Suf|DefaultSize, { 0, 0, 0} },
/* i386sl, i486sl, later 486, and Pentium. */
{"rsm", 0, 0x0faa, X, Cpu386, NoSuf, { 0, 0,
0} },
-{"bound", 2, 0x62, X, Cpu186, wlq_Suf|Modrm, { WordReg,
WordMem, 0} },
+{"bound", 2, 0x62, X, Cpu186|CpuNo64, wl_Suf|Modrm, {
WordReg, WordMem, 0} },
{"hlt", 0, 0xf4, X, 0, NoSuf, { 0, 0,
0} },
/* nop is actually 'xchgl %eax, %eax'. */
{"nop", 0, 0x90, X, 0, NoSuf, { 0, 0,
0} },
/* Protection control. */
-{"arpl", 2, 0x63, X, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16,
Reg16|ShortMem, 0} },
+{"arpl", 2, 0x63, X, Cpu286|CpuNo64, w_Suf|Modrm|IgnoreSize,{ Reg16,
Reg16|ShortMem, 0} },
{"lar", 2, 0x0f02, X, Cpu286, wlq_Suf|Modrm, {
WordReg|WordMem, WordReg, 0} },
-{"lgdt", 1, 0x0f01, 2, Cpu286, wlq_Suf|Modrm, {
WordMem, 0, 0} },
-{"lidt", 1, 0x0f01, 3, Cpu286, wlq_Suf|Modrm, {
WordMem, 0, 0} },
+{"lgdt", 1, 0x0f01, 2, Cpu286|CpuNo64,
wl_Suf|Modrm, { WordMem, 0, 0} },
+{"lgdt", 1, 0x0f01, 2, Cpu64, q_Suf|Modrm|NoRex64, {
LLongMem, 0, 0} },
+{"lidt", 1, 0x0f01, 3, Cpu286|CpuNo64,
wl_Suf|Modrm, { WordMem, 0, 0} },
+{"lidt", 1, 0x0f01, 3, Cpu64, q_Suf|Modrm|NoRex64, {
LLongMem, 0, 0} },
{"lldt", 1, 0x0f00, 2, Cpu286, w_Suf|Modrm|IgnoreSize,{
Reg16|ShortMem, 0, 0} },
{"lmsw", 1, 0x0f01, 6, Cpu286, w_Suf|Modrm|IgnoreSize,{
Reg16|ShortMem, 0, 0} },
{"lsl", 2, 0x0f03, X, Cpu286, wlq_Suf|Modrm, {
WordReg|WordMem, WordReg, 0} },
{"ltr", 1, 0x0f00, 3, Cpu286, w_Suf|Modrm|IgnoreSize,{
Reg16|ShortMem, 0, 0} },
-{"sgdt", 1, 0x0f01, 0, Cpu286, wlq_Suf|Modrm, {
WordMem, 0, 0} },
-{"sidt", 1, 0x0f01, 1, Cpu286, wlq_Suf|Modrm, {
WordMem, 0, 0} },
+{"sgdt", 1, 0x0f01, 0, Cpu286|CpuNo64,
wl_Suf|Modrm, { WordMem, 0, 0} },
+{"sgdt", 1, 0x0f01, 0, Cpu64, q_Suf|Modrm|NoRex64, {
LLongMem, 0, 0} },
+{"sidt", 1, 0x0f01, 1, Cpu286|CpuNo64,
wl_Suf|Modrm, { WordMem, 0, 0} },
+{"sidt", 1, 0x0f01, 1, Cpu64, q_Suf|Modrm, { LLongMem, 0,
0} },
{"sldt", 1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm, {
WordReg|InvMem, 0, 0} },
{"sldt", 1, 0x0f00, 0, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0,
0} },
{"smsw", 1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm, {
WordReg|InvMem, 0, 0} },
@@ -829,30 +845,30 @@
/* Opcode prefixes; we allow them as separate insns too. */
#define ADDR_PREFIX_OPCODE 0x67
-{"addr16", 0, 0x67, X, Cpu386,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"addr16", 0, 0x67, X, Cpu386|CpuNo64,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
{"addr32", 0, 0x67, X, Cpu386,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
-{"aword", 0, 0x67, X, Cpu386,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"aword", 0, 0x67, X, Cpu386|CpuNo64,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
{"adword", 0, 0x67, X, Cpu386,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
#define DATA_PREFIX_OPCODE 0x66
{"data16", 0, 0x66, X, Cpu386,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
-{"data32", 0, 0x66, X, Cpu386,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+{"data32", 0, 0x66, X, Cpu386|CpuNo64,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
{"word", 0, 0x66, X, Cpu386,
NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
-{"dword", 0, 0x66, X, Cpu386,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+{"dword", 0, 0x66, X, Cpu386|CpuNo64,
NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
#define LOCK_PREFIX_OPCODE 0xf0
{"lock", 0, 0xf0, X, 0, NoSuf|IsPrefix, { 0, 0, 0} },
{"wait", 0, 0x9b, X, 0, NoSuf|IsPrefix, { 0, 0, 0} },
#define CS_PREFIX_OPCODE 0x2e
-{"cs", 0, 0x2e, X, 0, NoSuf|IsPrefix, { 0, 0,
0} },
+{"cs", 0, 0x2e, X, CpuNo64,
NoSuf|IsPrefix, { 0, 0, 0} },
#define DS_PREFIX_OPCODE 0x3e
-{"ds", 0, 0x3e, X, 0, NoSuf|IsPrefix, { 0, 0,
0} },
+{"ds", 0, 0x3e, X, CpuNo64,
NoSuf|IsPrefix, { 0, 0, 0} },
#define ES_PREFIX_OPCODE 0x26
-{"es", 0, 0x26, X, 0, NoSuf|IsPrefix, { 0, 0,
0} },
+{"es", 0, 0x26, X, CpuNo64,
NoSuf|IsPrefix, { 0, 0, 0} },
#define FS_PREFIX_OPCODE 0x64
{"fs", 0, 0x64, X, Cpu386, NoSuf|IsPrefix, { 0, 0,
0} },
#define GS_PREFIX_OPCODE 0x65
{"gs", 0, 0x65, X, Cpu386, NoSuf|IsPrefix, { 0, 0,
0} },
#define SS_PREFIX_OPCODE 0x36
-{"ss", 0, 0x36, X, 0, NoSuf|IsPrefix, { 0, 0,
0} },
+{"ss", 0, 0x36, X, CpuNo64,
NoSuf|IsPrefix, { 0, 0, 0} },
#define REPNE_PREFIX_OPCODE 0xf2
#define REPE_PREFIX_OPCODE 0xf3
{"rep", 0, 0xf3, X, 0, NoSuf|IsPrefix, { 0, 0,
0} },