diff options
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r-- | opcodes/i386-dis.c | 50 |
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); |