This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] x86-64 opcodes correction
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Fri, 02 Jul 2004 14:21:31 +0200
- Subject: [PATCH] x86-64 opcodes correction
This is an update to the earlier sent out patch that wasn't accepted for
the
reason of the FSF copyright assignment not yet in place.
There is (at least) one thing in here that might need further
adjustment: far
(indirect) calls in 64-bit mode have, other than near calls, a default
operand
size of 32 bits, and they, even though only being able to deal with
48-bit
pointers, can push two 64-bit quantities on the stack when given a
rex64
override. The patch here doesn't permit this to be generated to be
consistent
with the respective far jumps and to prevent the impression that
through a 'q'
suffix one could make a far call to an 80-bit (16:64) pointer.
Additionally, when the previously sent out Intel syntax patch is
applied before
or after this one, then the intelbad test introduced by that patch will
fail
due to addtional diagnostics produced by this patch.
Jan
gas:
2004-07-02 Jan Beulich <jbeulich@novell.com>
* config/tc-i386.c: For DefaultSize instructions, don't guess a
'q'
suffix if the instruction doesn't support it.
* testsuite/gas/cfi/cfi-x86_64.d: Adjust expectation for leave
to
not have a rex prefix.
* testsuite/gas/i386/x86-64-inval.[ls]: Add a bunch of
instructions
illegal in 64-bit mode.
include:
2004-07-02 Jan Beulich <jbeulich@novell.com>
* opcode/i386.h: Adjust instruction descriptions to better
match the specification.
diff -Naur
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/config/tc-i386.c
2004-07-02.08.43-opcodes/gas/config/tc-i386.c
---
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/config/tc-i386.c 2004-06-28
16:51:56.000000000 +0200
+++ 2004-07-02.08.43-opcodes/gas/config/tc-i386.c 2004-07-02
10:39:10.878537872 +0200
@@ -2250,6 +2250,9 @@
else if ((i.tm.opcode_modifier & DefaultSize) && !i.suffix)
{
i.suffix = stackop_size;
+ if (i.suffix == QWORD_MNEM_SUFFIX
+ && (i.tm.opcode_modifier & No_qSuf))
+ i.suffix = LONG_MNEM_SUFFIX;
}
/* Change the opcode based on the operand size given by i.suffix;
diff -Naur
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/cfi/cfi-x86_64.d
2004-07-02.08.43-opcodes/gas/testsuite/gas/cfi/cfi-x86_64.d
---
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/cfi/cfi-x86_64.d 2004-03-07
11:04:42.000000000 +0100
+++
2004-07-02.08.43-opcodes/gas/testsuite/gas/cfi/cfi-x86_64.d 2004-07-02
10:39:10.879537720 +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
diff -Naur
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-inval.l
2004-07-02.08.43-opcodes/gas/testsuite/gas/i386/x86-64-inval.l
---
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-inval.l 2002-03-01
09:10:06.000000000 +0100
+++
2004-07-02.08.43-opcodes/gas/testsuite/gas/i386/x86-64-inval.l 2004-07-02
11:05:01.162858832 +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
diff -Naur
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-inval.s
2004-07-02.08.43-opcodes/gas/testsuite/gas/i386/x86-64-inval.s
---
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/gas/testsuite/gas/i386/x86-64-inval.s 2002-03-01
09:10:06.000000000 +0100
+++
2004-07-02.08.43-opcodes/gas/testsuite/gas/i386/x86-64-inval.s 2004-06-01
13:05:39.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
diff -Naur
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/include/opcode/i386.h
2004-07-02.08.43-opcodes/include/opcode/i386.h
---
/home/jbeulich/src/binutils/mainline/2004-07-02.08.43/include/opcode/i386.h 2004-06-28
16:52:01.000000000 +0200
+++ 2004-07-02.08.43-opcodes/include/opcode/i386.h 2004-07-02
10:39:10.883537112 +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,12 +177,23 @@
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 } },
/* In/out from ports. */
+/* XXX should reject %rax */
{"in", 2, 0xe4, X, 0, bwl_Suf|W, { Imm8,
Acc, 0 } },
{"in", 2, 0xec, X, 0, bwl_Suf|W, {
InOutPortReg, Acc, 0 } },
{"in", 1, 0xe4, X, 0, bwl_Suf|W, { Imm8,
0, 0 } },
@@ -196,11 +207,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 +221,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 +287,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 +381,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, {
Disp16|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, {
Reg16|Reg64|WordMem|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} },
+{"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, 0, wl_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} },
-
-{"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} },
+{"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, 0, wl_Suf|Modrm, {
WordMem|JumpAbsolute, 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 +552,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} },
@@ -827,30 +843,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} },