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.c75
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)