aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 2eb2c42..703f09d 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -230,7 +230,6 @@ struct instr_info
bool b;
bool no_broadcast;
bool nf;
- bool u;
}
vex;
@@ -524,6 +523,7 @@ fetch_error (const instr_info *ins)
#define Xz { OP_DSreg, eSI_reg }
#define Yb { OP_ESreg, eDI_reg }
#define Yv { OP_ESreg, eDI_reg }
+#define DSCX { OP_DSreg, eCX_reg }
#define DSBX { OP_DSreg, eBX_reg }
#define es { OP_REG, es_reg }
@@ -1346,6 +1346,7 @@ enum
X86_64_0F01_REG_5_MOD_3_RM_6_PREFIX_1,
X86_64_0F01_REG_5_MOD_3_RM_7_PREFIX_1,
X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1,
+ X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_3,
X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1,
X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3,
X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1,
@@ -2305,7 +2306,7 @@ static const struct dis386 dis386_twobyte[] = {
{ "sysenter", { SEP }, PREFIX_REX2_ILLEGAL },
{ "sysexit%LQ", { SEP }, PREFIX_REX2_ILLEGAL },
{ Bad_Opcode },
- { "getsec", { XX }, 0 },
+ { "getsec", { XX }, PREFIX_REX2_ILLEGAL },
/* 38 */
{ THREE_BYTE_TABLE (THREE_BYTE_0F38) },
{ Bad_Opcode },
@@ -2975,6 +2976,8 @@ static const struct dis386 reg_table[][8] = {
{ "xsha384", { { OP_0f07, 0 } }, 0 },
{ "xsha512", { { OP_0f07, 0 } }, 0 },
{ PREFIX_TABLE (PREFIX_0FA6_REG_5) },
+ { "montmul2", { { OP_0f07, 0 } }, 0 },
+ { "xmodexp", { { OP_0f07, 0 } }, 0 },
},
/* REG_0FA7 */
{
@@ -3252,6 +3255,8 @@ static const struct dis386 prefix_table[][4] = {
{
{ "rdpru", { Skip_MODRM }, 0 },
{ X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_1) },
+ { Bad_Opcode },
+ { X86_64_TABLE (X86_64_0F01_REG_7_MOD_3_RM_5_PREFIX_3) },
},
/* PREFIX_0F01_REG_7_MOD_3_RM_6 */
@@ -4631,6 +4636,12 @@ static const struct dis386 x86_64_table[][2] = {
{ "rmpquery", { Skip_MODRM }, 0 },
},
+ /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */
+ {
+ { Bad_Opcode },
+ { "rmpread", { DSCX, RMrAX, Skip_MODRM }, 0 },
+ },
+
/* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_1 */
{
{ Bad_Opcode },
@@ -4640,7 +4651,7 @@ static const struct dis386 x86_64_table[][2] = {
/* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */
{
{ Bad_Opcode },
- { "rmpupdate", { Skip_MODRM }, 0 },
+ { "rmpupdate", { RMrAX, DSCX, Skip_MODRM }, 0 },
},
/* X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1 */
@@ -9440,8 +9451,6 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins)
if (!(*ins->codep & 0x4))
ins->rex2 |= REX_X;
- ins->vex.u = *ins->codep & 0x4;
-
switch ((*ins->codep & 0x3))
{
case 0:
@@ -9476,8 +9485,8 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins)
{
/* Report bad for !evex_default and when two fixed values of evex
change. */
- if (ins->evex_type != evex_default || (ins->rex2 & REX_B)
- || ((ins->rex2 & REX_X) && (ins->modrm.mod != 3)))
+ if (ins->evex_type != evex_default
+ || (ins->rex2 & (REX_B | REX_X)))
return &bad_opcode;
/* In 16/32-bit mode silently ignore following bits. */
ins->rex &= ~REX_B;
@@ -9501,22 +9510,14 @@ get_valid_dis386 (const struct dis386 *dp, instr_info *ins)
if (!fetch_modrm (ins))
return &err_opcode;
- /* When modrm.mod != 3, the U bit is used by APX for bit X4.
- When modrm.mod == 3, the U bit is used by AVX10. The U bit and
- the b bit should not be zero at the same time. */
- if (ins->modrm.mod == 3 && !ins->vex.u && !ins->vex.b)
+ if (ins->modrm.mod == 3 && (ins->rex2 & REX_X))
return &bad_opcode;
/* Set vector length. For EVEX-promoted instructions, evex.ll == 0b00,
which has the same encoding as vex.length == 128 and they can share
the same processing with vex.length in OP_VEX. */
if (ins->modrm.mod == 3 && ins->vex.b && ins->evex_type != evex_from_legacy)
- {
- if (ins->vex.u)
- ins->vex.length = 512;
- else
- ins->vex.length = 256;
- }
+ ins->vex.length = 512;
else
{
switch (ins->vex.ll)
@@ -13126,8 +13127,11 @@ OP_ESreg (instr_info *ins, int code, int sizeflag)
intel_operand_size (ins, b_mode, sizeflag);
}
}
- oappend_register (ins, att_names_seg[0]);
- oappend_char (ins, ':');
+ if (ins->address_mode != mode_64bit)
+ {
+ oappend_register (ins, att_names_seg[0]);
+ oappend_char (ins, ':');
+ }
ptr_reg (ins, code, sizeflag);
return true;
}
@@ -13139,6 +13143,8 @@ OP_DSreg (instr_info *ins, int code, int sizeflag)
{
switch (ins->codep[-1])
{
+ case 0x01: /* rmpupdate/rmpread */
+ break;
case 0x6f: /* outsw/outsl */
intel_operand_size (ins, z_mode, sizeflag);
break;
@@ -13151,9 +13157,9 @@ OP_DSreg (instr_info *ins, int code, int sizeflag)
intel_operand_size (ins, b_mode, sizeflag);
}
}
- /* Set ins->active_seg_prefix to PREFIX_DS if it is unset so that the
- default segment register DS is printed. */
- if (!ins->active_seg_prefix)
+ /* Outside of 64-bit mode set ins->active_seg_prefix to PREFIX_DS if it
+ is unset, so that the default segment register DS is printed. */
+ if (ins->address_mode != mode_64bit && !ins->active_seg_prefix)
ins->active_seg_prefix = PREFIX_DS;
append_seg (ins);
ptr_reg (ins, code, sizeflag);