static void OP_XS (int, int);
static void OP_M (int, int);
static void OP_VEX (int, int);
+static void OP_VEX_FMA (int, int);
static void OP_EX_Vex (int, int);
+static void OP_EX_VexW (int, int);
static void OP_XMM_Vex (int, int);
+static void OP_XMM_VexW (int, int);
static void OP_REG_VexI4 (int, int);
static void PCLMUL_Fixup (int, int);
+static void VEXI4_Fixup (int, int);
static void VZERO_Fixup (int, int);
static void VCMP_Fixup (int, int);
static void OP_0f07 (int, int);
#define Vex { OP_VEX, vex_mode }
#define Vex128 { OP_VEX, vex128_mode }
#define Vex256 { OP_VEX, vex256_mode }
+#define VexI4 { VEXI4_Fixup, 0}
+#define VexFMA { OP_VEX_FMA, vex_mode }
+#define Vex128FMA { OP_VEX_FMA, vex128_mode }
#define EXdVex { OP_EX_Vex, d_mode }
#define EXdVexS { OP_EX_Vex, d_swap_mode }
#define EXqVex { OP_EX_Vex, q_mode }
#define EXqVexS { OP_EX_Vex, q_swap_mode }
+#define EXVexW { OP_EX_VexW, x_mode }
+#define EXdVexW { OP_EX_VexW, d_mode }
+#define EXqVexW { OP_EX_VexW, q_mode }
#define XMVex { OP_XMM_Vex, 0 }
+#define XMVexW { OP_XMM_VexW, 0 }
#define XMVexI4 { OP_REG_VexI4, x_mode }
#define PCLMUL { PCLMUL_Fixup, 0 }
#define VZERO { VZERO_Fixup, 0 }
#define PREFIX_VEX_3A4A (PREFIX_VEX_3A44 + 1)
#define PREFIX_VEX_3A4B (PREFIX_VEX_3A4A + 1)
#define PREFIX_VEX_3A4C (PREFIX_VEX_3A4B + 1)
-#define PREFIX_VEX_3A60 (PREFIX_VEX_3A4C + 1)
+#define PREFIX_VEX_3A5C (PREFIX_VEX_3A4C + 1)
+#define PREFIX_VEX_3A5D (PREFIX_VEX_3A5C + 1)
+#define PREFIX_VEX_3A5E (PREFIX_VEX_3A5D + 1)
+#define PREFIX_VEX_3A5F (PREFIX_VEX_3A5E + 1)
+#define PREFIX_VEX_3A60 (PREFIX_VEX_3A5F + 1)
#define PREFIX_VEX_3A61 (PREFIX_VEX_3A60 + 1)
#define PREFIX_VEX_3A62 (PREFIX_VEX_3A61 + 1)
#define PREFIX_VEX_3A63 (PREFIX_VEX_3A62 + 1)
-#define PREFIX_VEX_3ADF (PREFIX_VEX_3A63 + 1)
+#define PREFIX_VEX_3A68 (PREFIX_VEX_3A63 + 1)
+#define PREFIX_VEX_3A69 (PREFIX_VEX_3A68 + 1)
+#define PREFIX_VEX_3A6A (PREFIX_VEX_3A69 + 1)
+#define PREFIX_VEX_3A6B (PREFIX_VEX_3A6A + 1)
+#define PREFIX_VEX_3A6C (PREFIX_VEX_3A6B + 1)
+#define PREFIX_VEX_3A6D (PREFIX_VEX_3A6C + 1)
+#define PREFIX_VEX_3A6E (PREFIX_VEX_3A6D + 1)
+#define PREFIX_VEX_3A6F (PREFIX_VEX_3A6E + 1)
+#define PREFIX_VEX_3A78 (PREFIX_VEX_3A6F + 1)
+#define PREFIX_VEX_3A79 (PREFIX_VEX_3A78 + 1)
+#define PREFIX_VEX_3A7A (PREFIX_VEX_3A79 + 1)
+#define PREFIX_VEX_3A7B (PREFIX_VEX_3A7A + 1)
+#define PREFIX_VEX_3A7C (PREFIX_VEX_3A7B + 1)
+#define PREFIX_VEX_3A7D (PREFIX_VEX_3A7C + 1)
+#define PREFIX_VEX_3A7E (PREFIX_VEX_3A7D + 1)
+#define PREFIX_VEX_3A7F (PREFIX_VEX_3A7E + 1)
+#define PREFIX_VEX_3ADF (PREFIX_VEX_3A7F + 1)
#define X86_64_06 0
#define X86_64_07 (X86_64_06 + 1)
#define VEX_LEN_3A61_P_2 (VEX_LEN_3A60_P_2 + 1)
#define VEX_LEN_3A62_P_2 (VEX_LEN_3A61_P_2 + 1)
#define VEX_LEN_3A63_P_2 (VEX_LEN_3A62_P_2 + 1)
-#define VEX_LEN_3ADF_P_2 (VEX_LEN_3A63_P_2 + 1)
+#define VEX_LEN_3A6A_P_2 (VEX_LEN_3A63_P_2 + 1)
+#define VEX_LEN_3A6B_P_2 (VEX_LEN_3A6A_P_2 + 1)
+#define VEX_LEN_3A6E_P_2 (VEX_LEN_3A6B_P_2 + 1)
+#define VEX_LEN_3A6F_P_2 (VEX_LEN_3A6E_P_2 + 1)
+#define VEX_LEN_3A7A_P_2 (VEX_LEN_3A6F_P_2 + 1)
+#define VEX_LEN_3A7B_P_2 (VEX_LEN_3A7A_P_2 + 1)
+#define VEX_LEN_3A7E_P_2 (VEX_LEN_3A7B_P_2 + 1)
+#define VEX_LEN_3A7F_P_2 (VEX_LEN_3A7E_P_2 + 1)
+#define VEX_LEN_3ADF_P_2 (VEX_LEN_3A7F_P_2 + 1)
typedef void (*op_rtn) (int bytemode, int sizeflag);
{ "(bad)", { XX } },
},
+ /* PREFIX_VEX_3A5C */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmaddsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A5D */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmaddsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A5E */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmsubaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A5F */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmsubaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
/* PREFIX_VEX_3A60 */
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
+ /* PREFIX_VEX_3A68 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A69 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6A */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A6A_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6B */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A6B_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6C */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6D */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6E */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A6E_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A6F */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A6F_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A78 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfnmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A79 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfnmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7A */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A7A_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7B */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A7B_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7C */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfnmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7D */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "vfnmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7E */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A7E_P_2) },
+ { "(bad)", { XX } },
+ },
+
+ /* PREFIX_VEX_3A7F */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { VEX_LEN_TABLE (VEX_LEN_3A7F_P_2) },
+ { "(bad)", { XX } },
+ },
+
/* PREFIX_VEX_3ADF */
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREFIX_TABLE (PREFIX_VEX_3A5C) },
+ { PREFIX_TABLE (PREFIX_VEX_3A5D) },
+ { PREFIX_TABLE (PREFIX_VEX_3A5E) },
+ { PREFIX_TABLE (PREFIX_VEX_3A5F) },
/* 60 */
{ PREFIX_TABLE (PREFIX_VEX_3A60) },
{ PREFIX_TABLE (PREFIX_VEX_3A61) },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
/* 68 */
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREFIX_TABLE (PREFIX_VEX_3A68) },
+ { PREFIX_TABLE (PREFIX_VEX_3A69) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6A) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6B) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6C) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6D) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6E) },
+ { PREFIX_TABLE (PREFIX_VEX_3A6F) },
/* 70 */
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
/* 78 */
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { PREFIX_TABLE (PREFIX_VEX_3A78) },
+ { PREFIX_TABLE (PREFIX_VEX_3A79) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7A) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7B) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7C) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7D) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7E) },
+ { PREFIX_TABLE (PREFIX_VEX_3A7F) },
/* 80 */
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
- /* VEX_LEN_AE_R_2_M0 */
+ /* VEX_LEN_AE_R_2_M_0 */
{
{ "vldmxcsr", { Md } },
{ "(bad)", { XX } },
},
- /* VEX_LEN_AE_R_3_M0 */
+ /* VEX_LEN_AE_R_3_M_0 */
{
{ "vstmxcsr", { Md } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
+ /* VEX_LEN_3A6A_P_2 */
+ {
+ { "vfmaddss", { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A6B_P_2 */
+ {
+ { "vfmaddsd", { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A6E_P_2 */
+ {
+ { "vfmsubss", { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A6F_P_2 */
+ {
+ { "vfmsubsd", { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A7A_P_2 */
+ {
+ { "vfnmaddss", { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A7B_P_2 */
+ {
+ { "vfnmaddsd", { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A7E_P_2 */
+ {
+ { "vfnmsubss", { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
+ /* VEX_LEN_3A7F_P_2 */
+ {
+ { "vfnmsubsd", { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+ { "(bad)", { XX } },
+ },
+
/* VEX_LEN_3ADF_P_2 */
{
{ "vaeskeygenassist", { XM, EXx, Ib } },
char *prefix_obufp;
if (info->mach == bfd_mach_x86_64_intel_syntax
- || info->mach == bfd_mach_x86_64)
+ || info->mach == bfd_mach_x86_64
+ || info->mach == bfd_mach_l1om
+ || info->mach == bfd_mach_l1om_intel_syntax)
address_mode = mode_64bit;
else
address_mode = mode_32bit;
if (intel_syntax == (char) -1)
intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax);
+ || info->mach == bfd_mach_x86_64_intel_syntax
+ || info->mach == bfd_mach_l1om_intel_syntax);
if (info->mach == bfd_mach_i386_i386
|| info->mach == bfd_mach_x86_64
+ || info->mach == bfd_mach_l1om
|| info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax)
+ || info->mach == bfd_mach_x86_64_intel_syntax
+ || info->mach == bfd_mach_l1om_intel_syntax)
priv.orig_sizeflag = AFLAG | DFLAG;
else if (info->mach == bfd_mach_i386_i8086)
priv.orig_sizeflag = 0;
}
/* The output looks better if we put 7 bytes on a line, since that
- puts most long word instructions on a single line. */
- info->bytes_per_line = 7;
+ puts most long word instructions on a single line. Use 8 bytes
+ for Intel L1OM. */
+ if (info->mach == bfd_mach_l1om
+ || info->mach == bfd_mach_l1om_intel_syntax)
+ info->bytes_per_line = 8;
+ else
+ info->bytes_per_line = 7;
info->private_data = &priv;
priv.max_fetched = priv.the_buffer;
/* db_4 6 */
{
- "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
- "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
},
/* de_3 7 */
/* Capital letters in template are macros. */
static int
-putop (const char *template, int sizeflag)
+putop (const char *in_template, int sizeflag)
{
const char *p;
int alt = 0;
else \
abort ();
- for (p = template; *p; p++)
+ for (p = in_template; *p; p++)
{
switch (*p)
{
*obufp++ = '+';
*obufp = '\0';
}
- else if (modrm.mod != 1)
+ else if (modrm.mod != 1 && disp != -disp)
{
*obufp++ = '-';
*obufp = '\0';
oappend (scratchbuf + intel_syntax);
}
+/* Get the VEX immediate byte without moving codep. */
+
+static unsigned char
+get_vex_imm8 (int sizeflag)
+{
+ int bytes_before_imm = 0;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ if (modrm.mod != 3)
+ {
+ /* There are SIB/displacement bytes. */
+ if ((sizeflag & AFLAG) || address_mode == mode_64bit)
+ {
+ /* 32/64 bit address mode */
+ int base = modrm.rm;
+
+ /* Check SIB byte. */
+ if (base == 4)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ base = *codep & 7;
+ bytes_before_imm++;
+ }
+
+ switch (modrm.mod)
+ {
+ case 0:
+ /* When modrm.rm == 5 or modrm.rm == 4 and base in
+ SIB == 5, there is a 4 byte displacement. */
+ if (base != 5)
+ /* No displacement. */
+ break;
+ case 2:
+ /* 4 byte displacement. */
+ bytes_before_imm += 4;
+ break;
+ case 1:
+ /* 1 byte displacement. */
+ bytes_before_imm++;
+ break;
+ }
+ }
+ else
+ { /* 16 bit address mode */
+ switch (modrm.mod)
+ {
+ case 0:
+ /* When modrm.rm == 6, there is a 2 byte displacement. */
+ if (modrm.rm != 6)
+ /* No displacement. */
+ break;
+ case 2:
+ /* 2 byte displacement. */
+ bytes_before_imm += 2;
+ break;
+ case 1:
+ /* 1 byte displacement. */
+ bytes_before_imm++;
+ break;
+ }
+ }
+ }
+
+ FETCH_DATA (the_info, codep + bytes_before_imm + 1);
+ return codep [bytes_before_imm];
+}
+
+static void
+OP_EX_VexReg (int bytemode, int sizeflag, int reg)
+{
+ if (reg == -1 && modrm.mod != 3)
+ {
+ OP_E_memory (bytemode, sizeflag);
+ return;
+ }
+ else
+ {
+ if (reg == -1)
+ {
+ reg = modrm.rm;
+ USED_REX (REX_B);
+ if (rex & REX_B)
+ reg += 8;
+ }
+ else if (reg > 7 && address_mode != mode_64bit)
+ BadOp ();
+ }
+
+ switch (vex.length)
+ {
+ case 128:
+ sprintf (scratchbuf, "%%xmm%d", reg);
+ break;
+ case 256:
+ sprintf (scratchbuf, "%%ymm%d", reg);
+ break;
+ default:
+ abort ();
+ }
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EX_VexW (int bytemode, int sizeflag)
+{
+ int reg = -1;
+
+ if (!vex_w_done)
+ {
+ vex_w_done = 1;
+ if (vex.w)
+ reg = vex.register_specifier;
+ }
+ else
+ {
+ if (!vex.w)
+ reg = vex.register_specifier;
+ }
+
+ OP_EX_VexReg (bytemode, sizeflag, reg);
+}
+
+static void
+OP_VEX_FMA (int bytemode, int sizeflag)
+{
+ int reg = get_vex_imm8 (sizeflag) >> 4;
+
+ if (reg > 7 && address_mode != mode_64bit)
+ BadOp ();
+
+ switch (vex.length)
+ {
+ case 128:
+ switch (bytemode)
+ {
+ case vex_mode:
+ case vex128_mode:
+ break;
+ default:
+ abort ();
+ return;
+ }
+
+ sprintf (scratchbuf, "%%xmm%d", reg);
+ break;
+ case 256:
+ switch (bytemode)
+ {
+ case vex_mode:
+ break;
+ default:
+ abort ();
+ return;
+ }
+
+ sprintf (scratchbuf, "%%ymm%d", reg);
+ break;
+ default:
+ abort ();
+ }
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+VEXI4_Fixup (int bytemode ATTRIBUTE_UNUSED,
+ int sizeflag ATTRIBUTE_UNUSED)
+{
+ /* Skip the immediate byte and check for invalid bits. */
+ FETCH_DATA (the_info, codep + 1);
+ if (*codep++ & 0xf)
+ BadOp ();
+}
+
static void
OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
oappend (scratchbuf + intel_syntax);
}
+static void
+OP_XMM_VexW (int bytemode, int sizeflag)
+{
+ /* Turn off the REX.W bit since it is used for swapping operands
+ now. */
+ rex &= ~REX_W;
+ OP_XMM (bytemode, sizeflag);
+}
+
static void
OP_EX_Vex (int bytemode, int sizeflag)
{