diff options
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r-- | opcodes/i386-dis.c | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index a3e216e..34dcd10 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -91,6 +91,7 @@ static void OP_M (int, int); static void OP_VEX (int, int); static void OP_EX_Vex (int, int); static void OP_EX_VexW (int, int); +static void OP_EX_VexImmW (int, int); static void OP_XMM_Vex (int, int); static void OP_XMM_VexW (int, int); static void OP_REG_VexI4 (int, int); @@ -380,6 +381,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define EXVexW { OP_EX_VexW, x_mode } #define EXdVexW { OP_EX_VexW, d_mode } #define EXqVexW { OP_EX_VexW, q_mode } +#define EXVexImmW { OP_EX_VexImmW, x_mode } #define XMVex { OP_XMM_Vex, 0 } #define XMVexScalar { OP_XMM_Vex, scalar_mode } #define XMVexW { OP_XMM_VexW, 0 } @@ -1032,6 +1034,8 @@ enum PREFIX_VEX_3A41, PREFIX_VEX_3A42, PREFIX_VEX_3A44, + PREFIX_VEX_3A48, + PREFIX_VEX_3A49, PREFIX_VEX_3A4A, PREFIX_VEX_3A4B, PREFIX_VEX_3A4C, @@ -1570,6 +1574,8 @@ enum VEX_W_3A41_P_2, VEX_W_3A42_P_2, VEX_W_3A44_P_2, + VEX_W_3A48_P_2, + VEX_W_3A49_P_2, VEX_W_3A4A_P_2, VEX_W_3A4B_P_2, VEX_W_3A4C_P_2, @@ -5087,6 +5093,20 @@ static const struct dis386 prefix_table[][4] = { { VEX_LEN_TABLE (VEX_LEN_3A44_P_2) }, }, + /* PREFIX_VEX_3A48 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { VEX_W_TABLE (VEX_W_3A48_P_2) }, + }, + + /* PREFIX_VEX_3A49 */ + { + { Bad_Opcode }, + { Bad_Opcode }, + { VEX_W_TABLE (VEX_W_3A49_P_2) }, + }, + /* PREFIX_VEX_3A4A */ { { Bad_Opcode }, @@ -7858,8 +7878,8 @@ static const struct dis386 vex_table[][256] = { { Bad_Opcode }, { Bad_Opcode }, /* 48 */ - { Bad_Opcode }, - { Bad_Opcode }, + { PREFIX_TABLE (PREFIX_VEX_3A48) }, + { PREFIX_TABLE (PREFIX_VEX_3A49) }, { PREFIX_TABLE (PREFIX_VEX_3A4A) }, { PREFIX_TABLE (PREFIX_VEX_3A4B) }, { PREFIX_TABLE (PREFIX_VEX_3A4C) }, @@ -10118,6 +10138,16 @@ static const struct dis386 vex_w_table[][2] = { { "vpclmulqdq", { XM, Vex128, EXx, PCLMUL } }, }, { + /* VEX_W_3A48_P_2 */ + { "vpermil2ps", { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } }, + { "vpermil2ps", { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } }, + }, + { + /* VEX_W_3A49_P_2 */ + { "vpermil2pd", { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } }, + { "vpermil2pd", { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } }, + }, + { /* VEX_W_3A4A_P_2 */ { "vblendvps", { XM, Vex, EXx, XMVexI4 } }, }, @@ -14581,6 +14611,47 @@ OP_EX_VexReg (int bytemode, int sizeflag, int reg) } static void +OP_EX_VexImmW (int bytemode, int sizeflag) +{ + int reg = -1; + static unsigned char vex_imm8; + + if (vex_w_done == 0) + { + vex_w_done = 1; + + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; + + vex_imm8 = get_vex_imm8 (sizeflag, 0); + + if (vex.w) + reg = vex_imm8 >> 4; + + OP_EX_VexReg (bytemode, sizeflag, reg); + } + else if (vex_w_done == 1) + { + vex_w_done = 2; + + if (!vex.w) + reg = vex_imm8 >> 4; + + OP_EX_VexReg (bytemode, sizeflag, reg); + } + else + { + /* Output the imm8 directly. */ + scratchbuf[0] = '$'; + print_operand_value (scratchbuf + 1, 1, vex_imm8 & 0xf); + oappend (scratchbuf + intel_syntax); + scratchbuf[0] = '\0'; + codep++; + } +} + +static void OP_Vex_2src (int bytemode, int sizeflag) { if (modrm.mod == 3) |