static int rex;
/* Bits of REX we've already used. */
static int rex_used;
-/* REX bits in original REX prefix ignored. */
-static int rex_ignored;
/* Mark parts used in the REX prefix. When we are testing for
empty prefix (for 8bit register REX extension), just mask it
out. Otherwise test for REX bit is excuse for existence of REX
#define EXxmm_mw { OP_EX, xmm_mw_mode }
#define EXxmm_md { OP_EX, xmm_md_mode }
#define EXxmm_mq { OP_EX, xmm_mq_mode }
-#define EXxmm_mdq { OP_EX, xmm_mdq_mode }
#define EXxmmdw { OP_EX, xmmdw_mode }
#define EXxmmqd { OP_EX, xmmqd_mode }
#define EXymmq { OP_EX, ymmq_mode }
xmm_md_mode,
/* XMM register or quad word memory operand */
xmm_mq_mode,
- /* XMM register or double/quad word memory operand, depending on
- VEX.W. */
- xmm_mdq_mode,
/* 16-byte XMM, word, double word or quad word operand. */
xmmdw_mode,
/* 16-byte XMM, double word, quad word operand or xmm word operand. */
MOD_0F01_REG_5,
MOD_0F01_REG_7,
MOD_0F12_PREFIX_0,
+ MOD_0F12_PREFIX_2,
MOD_0F13,
MOD_0F16_PREFIX_0,
+ MOD_0F16_PREFIX_2,
MOD_0F17,
MOD_0F18_REG_0,
MOD_0F18_REG_1,
MOD_0F2B_PREFIX_1,
MOD_0F2B_PREFIX_2,
MOD_0F2B_PREFIX_3,
- MOD_0F51,
+ MOD_0F50,
MOD_0F71_REG_2,
MOD_0F71_REG_4,
MOD_0F71_REG_6,
MOD_C4_32BIT,
MOD_C5_32BIT,
MOD_VEX_0F12_PREFIX_0,
+ MOD_VEX_0F12_PREFIX_2,
MOD_VEX_0F13,
MOD_VEX_0F16_PREFIX_0,
+ MOD_VEX_0F16_PREFIX_2,
MOD_VEX_0F17,
MOD_VEX_0F2B,
MOD_VEX_W_0_0F41_P_0_LEN_1,
MOD_VEX_W_1_0F3A33_P_2_LEN_0,
MOD_EVEX_0F12_PREFIX_0,
+ MOD_EVEX_0F12_PREFIX_2,
+ MOD_EVEX_0F13,
MOD_EVEX_0F16_PREFIX_0,
+ MOD_EVEX_0F16_PREFIX_2,
+ MOD_EVEX_0F17,
+ MOD_EVEX_0F2B,
MOD_EVEX_0F38C6_REG_1,
MOD_EVEX_0F38C6_REG_2,
MOD_EVEX_0F38C6_REG_5,
enum
{
PREFIX_90 = 0,
+ PREFIX_0F01_REG_3_RM_1,
PREFIX_0F01_REG_5_MOD_0,
PREFIX_0F01_REG_5_MOD_3_RM_0,
+ PREFIX_0F01_REG_5_MOD_3_RM_1,
PREFIX_0F01_REG_5_MOD_3_RM_2,
PREFIX_0F01_REG_7_MOD_3_RM_2,
PREFIX_0F01_REG_7_MOD_3_RM_3,
PREFIX_EVEX_0F10,
PREFIX_EVEX_0F11,
PREFIX_EVEX_0F12,
- PREFIX_EVEX_0F13,
- PREFIX_EVEX_0F14,
- PREFIX_EVEX_0F15,
PREFIX_EVEX_0F16,
- PREFIX_EVEX_0F17,
- PREFIX_EVEX_0F28,
- PREFIX_EVEX_0F29,
PREFIX_EVEX_0F2A,
- PREFIX_EVEX_0F2B,
PREFIX_EVEX_0F2C,
PREFIX_EVEX_0F2D,
PREFIX_EVEX_0F2E,
PREFIX_EVEX_0F2F,
PREFIX_EVEX_0F51,
- PREFIX_EVEX_0F54,
- PREFIX_EVEX_0F55,
- PREFIX_EVEX_0F56,
- PREFIX_EVEX_0F57,
PREFIX_EVEX_0F58,
PREFIX_EVEX_0F59,
PREFIX_EVEX_0F5A,
PREFIX_EVEX_0FC2,
PREFIX_EVEX_0FC4,
PREFIX_EVEX_0FC5,
- PREFIX_EVEX_0FC6,
PREFIX_EVEX_0FD1,
PREFIX_EVEX_0FD2,
PREFIX_EVEX_0FD3,
{
X86_64_06 = 0,
X86_64_07,
- X86_64_0D,
+ X86_64_0E,
X86_64_16,
X86_64_17,
X86_64_1E,
{
VEX_LEN_0F12_P_0_M_0 = 0,
VEX_LEN_0F12_P_0_M_1,
- VEX_LEN_0F12_P_2,
+#define VEX_LEN_0F12_P_2_M_0 VEX_LEN_0F12_P_0_M_0
VEX_LEN_0F13_M_0,
VEX_LEN_0F16_P_0_M_0,
VEX_LEN_0F16_P_0_M_1,
- VEX_LEN_0F16_P_2,
+#define VEX_LEN_0F16_P_2_M_0 VEX_LEN_0F16_P_0_M_0
VEX_LEN_0F17_M_0,
VEX_LEN_0F41_P_0,
VEX_LEN_0F41_P_2,
VEX_W_0F3ACE_P_2,
VEX_W_0F3ACF_P_2,
- EVEX_W_0F10_P_0,
EVEX_W_0F10_P_1,
- EVEX_W_0F10_P_2,
EVEX_W_0F10_P_3,
- EVEX_W_0F11_P_0,
EVEX_W_0F11_P_1,
- EVEX_W_0F11_P_2,
EVEX_W_0F11_P_3,
- EVEX_W_0F12_P_0_M_0,
EVEX_W_0F12_P_0_M_1,
EVEX_W_0F12_P_1,
- EVEX_W_0F12_P_2,
EVEX_W_0F12_P_3,
- EVEX_W_0F13_P_0,
- EVEX_W_0F13_P_2,
- EVEX_W_0F14_P_0,
- EVEX_W_0F14_P_2,
- EVEX_W_0F15_P_0,
- EVEX_W_0F15_P_2,
- EVEX_W_0F16_P_0_M_0,
EVEX_W_0F16_P_0_M_1,
EVEX_W_0F16_P_1,
- EVEX_W_0F16_P_2,
- EVEX_W_0F17_P_0,
- EVEX_W_0F17_P_2,
- EVEX_W_0F28_P_0,
- EVEX_W_0F28_P_2,
- EVEX_W_0F29_P_0,
- EVEX_W_0F29_P_2,
EVEX_W_0F2A_P_3,
- EVEX_W_0F2B_P_0,
- EVEX_W_0F2B_P_2,
- EVEX_W_0F2E_P_0,
- EVEX_W_0F2E_P_2,
- EVEX_W_0F2F_P_0,
- EVEX_W_0F2F_P_2,
- EVEX_W_0F51_P_0,
EVEX_W_0F51_P_1,
- EVEX_W_0F51_P_2,
EVEX_W_0F51_P_3,
- EVEX_W_0F54_P_0,
- EVEX_W_0F54_P_2,
- EVEX_W_0F55_P_0,
- EVEX_W_0F55_P_2,
- EVEX_W_0F56_P_0,
- EVEX_W_0F56_P_2,
- EVEX_W_0F57_P_0,
- EVEX_W_0F57_P_2,
- EVEX_W_0F58_P_0,
EVEX_W_0F58_P_1,
- EVEX_W_0F58_P_2,
EVEX_W_0F58_P_3,
- EVEX_W_0F59_P_0,
EVEX_W_0F59_P_1,
- EVEX_W_0F59_P_2,
EVEX_W_0F59_P_3,
EVEX_W_0F5A_P_0,
EVEX_W_0F5A_P_1,
EVEX_W_0F5B_P_0,
EVEX_W_0F5B_P_1,
EVEX_W_0F5B_P_2,
- EVEX_W_0F5C_P_0,
EVEX_W_0F5C_P_1,
- EVEX_W_0F5C_P_2,
EVEX_W_0F5C_P_3,
- EVEX_W_0F5D_P_0,
EVEX_W_0F5D_P_1,
- EVEX_W_0F5D_P_2,
EVEX_W_0F5D_P_3,
- EVEX_W_0F5E_P_0,
EVEX_W_0F5E_P_1,
- EVEX_W_0F5E_P_2,
EVEX_W_0F5E_P_3,
- EVEX_W_0F5F_P_0,
EVEX_W_0F5F_P_1,
- EVEX_W_0F5F_P_2,
EVEX_W_0F5F_P_3,
EVEX_W_0F62_P_2,
EVEX_W_0F66_P_2,
EVEX_W_0F7F_P_1,
EVEX_W_0F7F_P_2,
EVEX_W_0F7F_P_3,
- EVEX_W_0FC2_P_0,
EVEX_W_0FC2_P_1,
- EVEX_W_0FC2_P_2,
EVEX_W_0FC2_P_3,
- EVEX_W_0FC6_P_0,
- EVEX_W_0FC6_P_2,
EVEX_W_0FD2_P_2,
EVEX_W_0FD3_P_2,
EVEX_W_0FD4_P_2,
'H' => print ",pt" or ",pn" branch hint
'I' => honor following macro letter even in Intel mode (implemented only
for some of the macro letters)
- 'J' => print 'l'
+ 'J' unused.
'K' => print 'd' or 'q' if rex prefix is present.
'L' => print 'l' if suffix_always is true
'M' => print 'r' if intel_mnemonic is false.
'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
'!' => change condition from true to false or from false to true.
'%' => add 1 upper case letter to the macro.
- '^' => print 'w' or 'l' depending on operand size prefix or
- suffix_always is true (lcall/ljmp).
+ '^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
+ prefix or suffix_always is true (lcall/ljmp).
'@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending
on operand size prefix.
'&' => print 'q' in 64bit mode for Intel64 ISA or if instruction
"XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
register operands and no broadcast.
"XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
- "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand
- or suffix_always is true
+ "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory
+ operand or no operand at all in 64bit mode, or if suffix_always
+ is true.
"LB" => print "abs" in 64bit mode and behave as 'B' otherwise
"LS" => print "abs" in 64bit mode and behave as 'S' otherwise
"LV" => print "abs" for 64bit operand and behave as 'S' otherwise
{ "orS", { Gv, EvS }, 0 },
{ "orB", { AL, Ib }, 0 },
{ "orS", { eAX, Iv }, 0 },
- { X86_64_TABLE (X86_64_0D) },
+ { X86_64_TABLE (X86_64_0E) },
{ Bad_Opcode }, /* 0x0f extended opcode escape */
/* 10 */
{ "adcB", { Ebh1, Gb }, 0 },
/* c8 */
{ "enterT", { Iw, Ib }, 0 },
{ "leaveT", { XX }, 0 },
- { "Jret{|f}P", { Iw }, 0 },
- { "Jret{|f}P", { XX }, 0 },
+ { "{l|}ret{|f}P", { Iw }, 0 },
+ { "{l|}ret{|f}P", { XX }, 0 },
{ "int3", { XX }, 0 },
{ "int", { Ib }, 0 },
{ X86_64_TABLE (X86_64_CE) },
{ Bad_Opcode },
{ "syscall", { XX }, 0 },
{ "clts", { XX }, 0 },
- { "sysret%LP", { XX }, 0 },
+ { "sysret%LQ", { XX }, 0 },
/* 08 */
{ "invd", { XX }, 0 },
{ PREFIX_TABLE (PREFIX_0F09) },
{ "cmovleS", { Gv, Ev }, 0 },
{ "cmovgS", { Gv, Ev }, 0 },
/* 50 */
- { MOD_TABLE (MOD_0F51) },
+ { MOD_TABLE (MOD_0F50) },
{ PREFIX_TABLE (PREFIX_0F51) },
{ PREFIX_TABLE (PREFIX_0F52) },
{ PREFIX_TABLE (PREFIX_0F53) },
{ NULL, { { NULL, 0 } }, PREFIX_IGNORED }
},
+ /* PREFIX_0F01_REG_3_RM_1 */
+ {
+ { "vmmcall", { Skip_MODRM }, 0 },
+ { "vmgexit", { Skip_MODRM }, 0 },
+ { Bad_Opcode },
+ { "vmgexit", { Skip_MODRM }, 0 },
+ },
+
/* PREFIX_0F01_REG_5_MOD_0 */
{
{ Bad_Opcode },
/* PREFIX_0F01_REG_5_MOD_3_RM_0 */
{
- { Bad_Opcode },
+ { "serialize", { Skip_MODRM }, PREFIX_OPCODE },
{ "setssbsy", { Skip_MODRM }, PREFIX_OPCODE },
+ { Bad_Opcode },
+ { "xsusldtrk", { Skip_MODRM }, PREFIX_OPCODE },
+ },
+
+ /* PREFIX_0F01_REG_5_MOD_3_RM_1 */
+ {
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { Bad_Opcode },
+ { "xresldtrk", { Skip_MODRM }, PREFIX_OPCODE },
},
/* PREFIX_0F01_REG_5_MOD_3_RM_2 */
{
{ MOD_TABLE (MOD_0F12_PREFIX_0) },
{ "movsldup", { XM, EXx }, PREFIX_OPCODE },
- { "movlpd", { XM, EXq }, PREFIX_OPCODE },
+ { MOD_TABLE (MOD_0F12_PREFIX_2) },
{ "movddup", { XM, EXq }, PREFIX_OPCODE },
},
{
{ MOD_TABLE (MOD_0F16_PREFIX_0) },
{ "movshdup", { XM, EXx }, PREFIX_OPCODE },
- { "movhpd", { XM, EXq }, PREFIX_OPCODE },
+ { MOD_TABLE (MOD_0F16_PREFIX_2) },
},
/* PREFIX_0F1A */
{
{ MOD_TABLE (MOD_VEX_0F12_PREFIX_0) },
{ "vmovsldup", { XM, EXx }, 0 },
- { VEX_LEN_TABLE (VEX_LEN_0F12_P_2) },
+ { MOD_TABLE (MOD_VEX_0F12_PREFIX_2) },
{ "vmovddup", { XM, EXymmq }, 0 },
},
{
{ MOD_TABLE (MOD_VEX_0F16_PREFIX_0) },
{ "vmovshdup", { XM, EXx }, 0 },
- { VEX_LEN_TABLE (VEX_LEN_0F16_P_2) },
+ { MOD_TABLE (MOD_VEX_0F16_PREFIX_2) },
},
/* PREFIX_VEX_0F2A */
{ "popP", { es }, 0 },
},
- /* X86_64_0D */
+ /* X86_64_0E */
{
{ "pushP", { cs }, 0 },
},
/* X86_64_9A */
{
- { "Jcall{T|}", { Ap }, 0 },
+ { "{l|}call{T|}", { Ap }, 0 },
},
/* X86_64_C2 */
/* X86_64_EA */
{
- { "Jjmp{T|}", { Ap }, 0 },
+ { "{l|}jmp{T|}", { Ap }, 0 },
},
/* X86_64_0F01_REG_0 */
{ PREFIX_TABLE (PREFIX_VEX_0F11) },
{ PREFIX_TABLE (PREFIX_VEX_0F12) },
{ MOD_TABLE (MOD_VEX_0F13) },
- { "vunpcklpX", { XM, Vex, EXx }, 0 },
- { "vunpckhpX", { XM, Vex, EXx }, 0 },
+ { "vunpcklpX", { XM, Vex, EXx }, PREFIX_OPCODE },
+ { "vunpckhpX", { XM, Vex, EXx }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_VEX_0F16) },
{ MOD_TABLE (MOD_VEX_0F17) },
/* 18 */
{ Bad_Opcode },
{ Bad_Opcode },
/* 28 */
- { "vmovapX", { XM, EXx }, 0 },
- { "vmovapX", { EXxS, XM }, 0 },
+ { "vmovapX", { XM, EXx }, PREFIX_OPCODE },
+ { "vmovapX", { EXxS, XM }, PREFIX_OPCODE },
{ PREFIX_TABLE (PREFIX_VEX_0F2A) },
{ MOD_TABLE (MOD_VEX_0F2B) },
{ PREFIX_TABLE (PREFIX_VEX_0F2C) },
{ PREFIX_TABLE (PREFIX_VEX_0F51) },
{ PREFIX_TABLE (PREFIX_VEX_0F52) },
{ PREFIX_TABLE (PREFIX_VEX_0F53) },
- { "vandpX", { XM, Vex, EXx }, 0 },
- { "vandnpX", { XM, Vex, EXx }, 0 },
- { "vorpX", { XM, Vex, EXx }, 0 },
- { "vxorpX", { XM, Vex, EXx }, 0 },
+ { "vandpX", { XM, Vex, EXx }, PREFIX_OPCODE },
+ { "vandnpX", { XM, Vex, EXx }, PREFIX_OPCODE },
+ { "vorpX", { XM, Vex, EXx }, PREFIX_OPCODE },
+ { "vxorpX", { XM, Vex, EXx }, PREFIX_OPCODE },
/* 58 */
{ PREFIX_TABLE (PREFIX_VEX_0F58) },
{ PREFIX_TABLE (PREFIX_VEX_0F59) },
{ Bad_Opcode },
{ PREFIX_TABLE (PREFIX_VEX_0FC4) },
{ PREFIX_TABLE (PREFIX_VEX_0FC5) },
- { "vshufpX", { XM, Vex, EXx, Ib }, 0 },
+ { "vshufpX", { XM, Vex, EXx, Ib }, PREFIX_OPCODE },
{ Bad_Opcode },
/* c8 */
{ Bad_Opcode },
#include "i386-dis-evex.h"
static const struct dis386 vex_len_table[][2] = {
- /* VEX_LEN_0F12_P_0_M_0 */
+ /* VEX_LEN_0F12_P_0_M_0 / VEX_LEN_0F12_P_2_M_0 */
{
- { "vmovlps", { XM, Vex128, EXq }, 0 },
+ { "vmovlpX", { XM, Vex128, EXq }, 0 },
},
/* VEX_LEN_0F12_P_0_M_1 */
{ "vmovhlps", { XM, Vex128, EXq }, 0 },
},
- /* VEX_LEN_0F12_P_2 */
- {
- { "vmovlpd", { XM, Vex128, EXq }, 0 },
- },
-
/* VEX_LEN_0F13_M_0 */
{
- { "vmovlpX", { EXq, XM }, 0 },
+ { "vmovlpX", { EXq, XM }, PREFIX_OPCODE },
},
- /* VEX_LEN_0F16_P_0_M_0 */
+ /* VEX_LEN_0F16_P_0_M_0 / VEX_LEN_0F16_P_2_M_0 */
{
- { "vmovhps", { XM, Vex128, EXq }, 0 },
+ { "vmovhpX", { XM, Vex128, EXq }, 0 },
},
/* VEX_LEN_0F16_P_0_M_1 */
{ "vmovlhps", { XM, Vex128, EXq }, 0 },
},
- /* VEX_LEN_0F16_P_2 */
- {
- { "vmovhpd", { XM, Vex128, EXq }, 0 },
- },
-
/* VEX_LEN_0F17_M_0 */
{
- { "vmovhpX", { EXq, XM }, 0 },
+ { "vmovhpX", { EXq, XM }, PREFIX_OPCODE },
},
/* VEX_LEN_0F41_P_0 */
},
{
/* MOD_FF_REG_3 */
- { "Jcall^", { indirEp }, 0 },
+ { "{l|}call^", { indirEp }, 0 },
},
{
/* MOD_FF_REG_5 */
- { "Jjmp^", { indirEp }, 0 },
+ { "{l|}jmp^", { indirEp }, 0 },
},
{
/* MOD_0F01_REG_0 */
},
{
/* MOD_0F12_PREFIX_0 */
- { "movlps", { XM, EXq }, PREFIX_OPCODE },
- { "movhlps", { XM, EXq }, PREFIX_OPCODE },
+ { "movlpX", { XM, EXq }, 0 },
+ { "movhlps", { XM, EXq }, 0 },
+ },
+ {
+ /* MOD_0F12_PREFIX_2 */
+ { "movlpX", { XM, EXq }, 0 },
},
{
/* MOD_0F13 */
},
{
/* MOD_0F16_PREFIX_0 */
- { "movhps", { XM, EXq }, 0 },
+ { "movhpX", { XM, EXq }, 0 },
{ "movlhps", { XM, EXq }, 0 },
},
+ {
+ /* MOD_0F16_PREFIX_2 */
+ { "movhpX", { XM, EXq }, 0 },
+ },
{
/* MOD_0F17 */
{ "movhpX", { EXq, XM }, PREFIX_OPCODE },
{"movntsd", { Mq, XM }, PREFIX_OPCODE },
},
{
- /* MOD_0F51 */
+ /* MOD_0F50 */
{ Bad_Opcode },
{ "movmskpX", { Gdq, XS }, PREFIX_OPCODE },
},
{ VEX_LEN_TABLE (VEX_LEN_0F12_P_0_M_0) },
{ VEX_LEN_TABLE (VEX_LEN_0F12_P_0_M_1) },
},
+ {
+ /* MOD_VEX_0F12_PREFIX_2 */
+ { VEX_LEN_TABLE (VEX_LEN_0F12_P_2_M_0) },
+ },
{
/* MOD_VEX_0F13 */
{ VEX_LEN_TABLE (VEX_LEN_0F13_M_0) },
{ VEX_LEN_TABLE (VEX_LEN_0F16_P_0_M_0) },
{ VEX_LEN_TABLE (VEX_LEN_0F16_P_0_M_1) },
},
+ {
+ /* MOD_VEX_0F16_PREFIX_2 */
+ { VEX_LEN_TABLE (VEX_LEN_0F16_P_2_M_0) },
+ },
{
/* MOD_VEX_0F17 */
{ VEX_LEN_TABLE (VEX_LEN_0F17_M_0) },
},
{
/* MOD_VEX_0F2B */
- { "vmovntpX", { Mx, XM }, 0 },
+ { "vmovntpX", { Mx, XM }, PREFIX_OPCODE },
},
{
/* MOD_VEX_W_0_0F41_P_0_LEN_1 */
{
/* MOD_VEX_0F50 */
{ Bad_Opcode },
- { "vmovmskpX", { Gdq, XS }, 0 },
+ { "vmovmskpX", { Gdq, XS }, PREFIX_OPCODE },
},
{
/* MOD_VEX_0F71_REG_2 */
{
/* RM_0F01_REG_3 */
{ "vmrun", { Skip_MODRM }, 0 },
- { "vmmcall", { Skip_MODRM }, 0 },
+ { PREFIX_TABLE (PREFIX_0F01_REG_3_RM_1) },
{ "vmload", { Skip_MODRM }, 0 },
{ "vmsave", { Skip_MODRM }, 0 },
{ "stgi", { Skip_MODRM }, 0 },
{
/* RM_0F01_REG_5_MOD_3 */
{ PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_0) },
- { Bad_Opcode },
+ { PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_1) },
{ PREFIX_TABLE (PREFIX_0F01_REG_5_MOD_3_RM_2) },
{ Bad_Opcode },
{ Bad_Opcode },
{
int newrex, i, length;
rex = 0;
- rex_ignored = 0;
prefixes = 0;
used_prefixes = 0;
rex_used = 0;
case USE_XOP_8F_TABLE:
FETCH_DATA (info, codep + 3);
- /* All bits in the REX prefix are ignored. */
- rex_ignored = rex;
rex = ~(*codep >> 5) & 0x7;
/* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm". */
case USE_VEX_C4_TABLE:
/* VEX prefix. */
FETCH_DATA (info, codep + 3);
- /* All bits in the REX prefix are ignored. */
- rex_ignored = rex;
rex = ~(*codep >> 5) & 0x7;
switch ((*codep & 0x1f))
{
case USE_VEX_C5_TABLE:
/* VEX prefix. */
FETCH_DATA (info, codep + 2);
- /* All bits in the REX prefix are ignored. */
- rex_ignored = rex;
rex = (*codep & 0x80) ? 0 : REX_R;
/* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
/* EVEX prefix. */
vex.evex = 1;
FETCH_DATA (info, codep + 4);
- /* All bits in the REX prefix are ignored. */
- rex_ignored = rex;
/* The first byte after 0x62. */
rex = ~(*codep >> 5) & 0x7;
vex.r = *codep & 0x10;
else if (CONST_STRNEQ (p, "x86-64"))
{
address_mode = mode_64bit;
- priv.orig_sizeflag = AFLAG | DFLAG;
+ priv.orig_sizeflag |= AFLAG | DFLAG;
}
else if (CONST_STRNEQ (p, "i386"))
{
address_mode = mode_32bit;
- priv.orig_sizeflag = AFLAG | DFLAG;
+ priv.orig_sizeflag |= AFLAG | DFLAG;
}
else if (CONST_STRNEQ (p, "i8086"))
{
address_mode = mode_16bit;
- priv.orig_sizeflag = 0;
+ priv.orig_sizeflag &= ~(AFLAG | DFLAG);
}
else if (CONST_STRNEQ (p, "intel"))
{
}
/* Check if the REX prefix is used. */
- if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0)
+ if ((rex ^ rex_used) == 0 && !need_vex && last_rex_prefix >= 0)
all_prefixes[last_rex_prefix] = 0;
/* Check if the SEG prefix is used. */
/* Check if the DATA prefix is used. */
if ((prefixes & PREFIX_DATA) != 0
- && (used_prefixes & PREFIX_DATA) != 0)
+ && (used_prefixes & PREFIX_DATA) != 0
+ && !need_vex)
all_prefixes[last_data_prefix] = 0;
/* Print the extra prefixes. */
PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
separately. */
if (dp->prefix_requirement == PREFIX_OPCODE
- && dp != &bad_opcode
- && (((prefixes
- & (PREFIX_REPZ | PREFIX_REPNZ)) != 0
+ && (((need_vex
+ ? vex.prefix == REPE_PREFIX_OPCODE
+ || vex.prefix == REPNE_PREFIX_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))))
+ || (((need_vex
+ ? vex.prefix == DATA_PREFIX_OPCODE
+ : ((prefixes
+ & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
+ == PREFIX_DATA))
+ && (used_prefixes & PREFIX_DATA) == 0))
+ || (vex.evex && !vex.w != !(used_prefixes & PREFIX_DATA))))
{
(*info->fprintf_func) (info->stream, "(bad)");
return end_codep - priv.the_buffer;
"fist{l|}",
"fistp{l|}",
"(bad)",
- "fld{t||t|}",
+ "fld{t|}",
"(bad)",
- "fstp{t||t|}",
+ "fstp{t|}",
/* dc */
"fadd{l|}",
"fmul{l|}",
case 'B':
if (l == 0 && len == 1)
{
-case_B:
+ case_B:
if (intel_syntax)
break;
if (sizeflag & SUFFIX_ALWAYS)
*obufp++ = 'n';
}
break;
- case 'J':
- if (intel_syntax)
- break;
- *obufp++ = 'l';
- break;
case 'K':
USED_REX (REX_W);
if (rex & REX_W)
SAVE_LAST (*p);
break;
}
-case_L:
+ case_L:
if (intel_syntax)
break;
if (sizeflag & SUFFIX_ALWAYS)
case 'P':
if (l == 0 && len == 1)
{
-case_P:
+ case_P:
if (intel_syntax)
{
if ((rex & REX_W) == 0
case 'Q':
if (l == 0 && len == 1)
{
-case_Q:
+ case_Q:
if (intel_syntax && !alt)
break;
USED_REX (REX_W);
SAVE_LAST (*p);
break;
}
- if (intel_syntax
+ if ((intel_syntax && need_modrm)
|| (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)))
break;
if ((rex & REX_W))
USED_REX (REX_W);
*obufp++ = 'q';
}
- else
- *obufp++ = 'l';
+ else if((address_mode == mode_64bit && need_modrm)
+ || (sizeflag & SUFFIX_ALWAYS))
+ *obufp++ = intel_syntax? 'd' : 'l';
}
break;
case 'R':
case 'S':
if (l == 0 && len == 1)
{
-case_S:
+ case_S:
if (intel_syntax)
break;
if (sizeflag & SUFFIX_ALWAYS)
SAVE_LAST (*p);
break;
}
- if (need_vex && vex.prefix)
+ if (need_vex
+ ? vex.prefix == DATA_PREFIX_OPCODE
+ : prefixes & PREFIX_DATA)
{
- if (vex.prefix == DATA_PREFIX_OPCODE)
- *obufp++ = 'd';
- else
- *obufp++ = 's';
+ *obufp++ = 'd';
+ used_prefixes |= PREFIX_DATA;
}
else
- {
- if (prefixes & PREFIX_DATA)
- *obufp++ = 'd';
- else
- *obufp++ = 's';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
+ *obufp++ = 's';
break;
case 'Y':
if (l == 0 && len == 1)
case '^':
if (intel_syntax)
break;
+ if (isa64 == intel64 && (rex & REX_W))
+ {
+ USED_REX (REX_W);
+ *obufp++ = 'q';
+ break;
+ }
if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
{
if (sizeflag & DFLAG)
case o_mode:
oappend ("OWORD PTR ");
break;
- case xmm_mdq_mode:
case vex_scalar_w_dq_mode:
if (!need_vex)
abort ();
break;
}
/* fall through */
+ case vex_scalar_w_dq_mode:
case vex_vsib_d_w_dq_mode:
case vex_vsib_d_w_d_mode:
case vex_vsib_q_w_dq_mode:
case vex_vsib_q_w_d_mode:
case evex_x_gscat_mode:
- case xmm_mdq_mode:
shift = vex.w ? 3 : 2;
break;
case x_mode:
}
if ((havebase || haveindex || needindex || needaddr32 || riprel)
- && (bytemode != v_bnd_mode)
- && (bytemode != v_bndmk_mode)
- && (bytemode != bnd_mode)
- && (bytemode != bnd_swap_mode))
+ && (address_mode != mode_64bit
+ || ((bytemode != v_bnd_mode)
+ && (bytemode != v_bndmk_mode)
+ && (bytemode != bnd_mode)
+ && (bytemode != bnd_swap_mode))))
used_prefixes |= PREFIX_ADDR;
if (havedisp || (intel_syntax && riprel))
}
}
}
+ else if (bytemode == v_bnd_mode
+ || bytemode == v_bndmk_mode
+ || bytemode == bnd_mode
+ || bytemode == bnd_swap_mode)
+ {
+ oappend ("(bad)");
+ return;
+ }
else
{
/* 16 bit address mode */
&& bytemode != xmm_mw_mode
&& bytemode != xmm_md_mode
&& bytemode != xmm_mq_mode
- && bytemode != xmm_mdq_mode
&& bytemode != xmmq_mode
&& bytemode != evex_half_bcst_xmmq_mode
&& bytemode != ymm_mode
mnemonicendp = p;
*p = '\0';
-skip:
+ skip:
if (modrm.mod == 3)
{
int add;
mnemonicendp = p;
*p = '\0';
-skip:
+ skip:
OP_M (bytemode, sizeflag);
}
break;
}
-skip:
+ skip:
mnemonicendp = p;
*p = '\0';
OP_E (bytemode, sizeflag);