#define fs OP_REG, fs_reg
#define gs OP_REG, gs_reg
+#define MX OP_MMX, 0
+#define EM OP_EM, v_mode
+#define MS OP_MS, b_mode
+
typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
static int OP_E PARAMS ((int, int, int));
#if 0
static int OP_ONE PARAMS ((int, int, int));
#endif
+static int OP_MMX PARAMS ((int, int, int));
+static int OP_EM PARAMS ((int, int, int));
+static int OP_MS PARAMS ((int, int, int));
static void append_prefix PARAMS ((void));
static void set_op PARAMS ((int op));
#define GRP7 NULL, NULL, 14
#define GRP8 NULL, NULL, 15
#define GRP9 NULL, NULL, 16
+#define GRP10 NULL, NULL, 17
+#define GRP11 NULL, NULL, 18
+#define GRP12 NULL, NULL, 19
#define FLOATCODE 50
#define FLOAT NULL, NULL, FLOATCODE
{ "addS", Gv, Ev },
{ "addb", AL, Ib },
{ "addS", eAX, Iv },
- { "pushl", es },
- { "popl", es },
+ { "pushS", es },
+ { "popS", es },
/* 08 */
{ "orb", Eb, Gb },
{ "orS", Ev, Gv },
{ "orS", Gv, Ev },
{ "orb", AL, Ib },
{ "orS", eAX, Iv },
- { "pushl", cs },
+ { "pushS", cs },
{ "(bad)" }, /* 0x0f extended opcode escape */
/* 10 */
{ "adcb", Eb, Gb },
{ "adcS", Gv, Ev },
{ "adcb", AL, Ib },
{ "adcS", eAX, Iv },
- { "pushl", ss },
- { "popl", ss },
+ { "pushS", ss },
+ { "popS", ss },
/* 18 */
{ "sbbb", Eb, Gb },
{ "sbbS", Ev, Gv },
{ "sbbS", Gv, Ev },
{ "sbbb", AL, Ib },
{ "sbbS", eAX, Iv },
- { "pushl", ds },
- { "popl", ds },
+ { "pushS", ds },
+ { "popS", ds },
/* 20 */
{ "andb", Eb, Gb },
{ "andS", Ev, Gv },
/* 68 */
{ "pushS", Iv }, /* 386 book wrong */
{ "imulS", Gv, Ev, Iv },
- { "pushl", sIb }, /* push of byte really pushes 4 bytes */
+ { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */
{ "imulS", Gv, Ev, Ib },
{ "insb", Yb, indirDX },
{ "insS", Yv, indirDX },
{ "xchgS", eSI, eAX },
{ "xchgS", eDI, eAX },
/* 98 */
- { "cwtl" },
- { "cltd" },
+ { "cWtS" },
+ { "cStd" },
{ "lcall", Ap },
{ "(bad)" }, /* fwait */
{ "pushf" },
{ "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
{ "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
/* 60 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "punpcklbw", MX, EM },
+ { "punpcklwd", MX, EM },
+ { "punpckldq", MX, EM },
+ { "packsswb", MX, EM },
+ { "pcmpgtb", MX, EM },
+ { "pcmpgtw", MX, EM },
+ { "pcmpgtd", MX, EM },
+ { "packuswb", MX, EM },
/* 68 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "punpckhbw", MX, EM },
+ { "punpckhwd", MX, EM },
+ { "punpckhdq", MX, EM },
+ { "packssdw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ { "movd", MX, Ev },
+ { "movq", MX, EM },
/* 70 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM },
+ { "pcmpeqw", MX, EM },
+ { "pcmpeqd", MX, EM },
+ { "emms" },
/* 78 */
{ "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" },
+ { "movd", Ev, MX },
+ { "movq", EM, MX },
/* 80 */
{ "jo", Jv },
{ "jno", Jv },
{ "setle", Eb },
{ "setg", Eb },
/* a0 */
- { "pushl", fs },
- { "popl", fs },
+ { "pushS", fs },
+ { "popS", fs },
{ "cpuid" },
{ "btS", Ev, Gv },
{ "shldS", Ev, Gv, Ib },
{ "(bad)" },
{ "(bad)" },
/* a8 */
- { "pushl", gs },
- { "popl", gs },
+ { "pushS", gs },
+ { "popS", gs },
{ "rsm" },
{ "btsS", Ev, Gv },
{ "shrdS", Ev, Gv, Ib },
{ "bswap", eSI },
{ "bswap", eDI },
/* d0 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" },
+ { "psrlw", MX, EM },
+ { "psrld", MX, EM },
+ { "psrlq", MX, EM },
+ { "(bad)" },
+ { "pmullw", MX, EM },
+ { "(bad)" }, { "(bad)" },
/* d8 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "psubusb", MX, EM },
+ { "psubusw", MX, EM },
+ { "(bad)" },
+ { "pand", MX, EM },
+ { "paddusb", MX, EM },
+ { "paddusw", MX, EM },
+ { "(bad)" },
+ { "pandn", MX, EM },
/* e0 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" },
+ { "psraw", MX, EM },
+ { "psrad", MX, EM },
+ { "(bad)" },
+ { "(bad)" },
+ { "pmulhw", MX, EM },
+ { "(bad)" }, { "(bad)" },
/* e8 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "psubsb", MX, EM },
+ { "psubsw", MX, EM },
+ { "(bad)" },
+ { "por", MX, EM },
+ { "paddsb", MX, EM },
+ { "paddsw", MX, EM },
+ { "(bad)" },
+ { "pxor", MX, EM },
/* f0 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" },
+ { "psllw", MX, EM },
+ { "pslld", MX, EM },
+ { "psllq", MX, EM },
+ { "(bad)" },
+ { "pmaddwd", MX, EM },
+ { "(bad)" }, { "(bad)" },
/* f8 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "psubb", MX, EM },
+ { "psubw", MX, EM },
+ { "psubd", MX, EM },
+ { "(bad)" },
+ { "paddb", MX, EM },
+ { "paddw", MX, EM },
+ { "paddd", MX, EM },
+ { "(bad)" }
};
static const unsigned char onebyte_has_modrm[256] = {
};
static const unsigned char twobyte_has_modrm[256] = {
- 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+ /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
+ /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
+ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
+ /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
+ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
+ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
+ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,0,1, /* df */
+ /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
+ /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
};
static char obuf[100];
{ "(bad)" },
{ "(bad)" },
{ "(bad)" },
+ },
+ /* GRP10 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrlw", MS, Ib },
+ { "(bad)" },
+ { "psraw", MS, Ib },
+ { "(bad)" },
+ { "psllw", MS, Ib },
+ { "(bad)" },
+ },
+ /* GRP11 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrld", MS, Ib },
+ { "(bad)" },
+ { "psrad", MS, Ib },
+ { "(bad)" },
+ { "pslld", MS, Ib },
+ { "(bad)" },
+ },
+ /* GRP12 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrlq", MS, Ib },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "psllq", MS, Ib },
+ { "(bad)" },
}
};
if (prefixes & PREFIX_ADR)
{
aflag ^= 1;
- oappend ("addr16 ");
+ if (aflag)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
}
if (*codep == 0x0f)
else
*obufp++ = 'w';
break;
+ case 'W':
+ /* operand size flag for cwtl, cbtw */
+ if (dflag)
+ *obufp++ = 'w';
+ else
+ *obufp++ = 'b';
+ break;
}
}
*obufp = 0;
}
return (0);
}
+
+static int
+OP_MMX (bytemode, aflag, dflag)
+ int bytemode;
+ int aflag;
+ int dflag;
+{
+ sprintf (scratchbuf, "%%mm%d", reg);
+ oappend (scratchbuf);
+ return 0;
+}
+
+static int
+OP_EM (bytemode, aflag, dflag)
+ int bytemode;
+ int aflag;
+ int dflag;
+{
+ if (mod != 3)
+ return OP_E (bytemode, aflag, dflag);
+
+ codep++;
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf);
+ return 0;
+}
+
+static int
+OP_MS (bytemode, aflag, dflag)
+ int bytemode;
+ int aflag;
+ int dflag;
+{
+ ++codep;
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf);
+ return 0;
+}