aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2008-12-20 17:40:51 +0000
committerH.J. Lu <hjl.tools@gmail.com>2008-12-20 17:40:51 +0000
commitb6169b206a513cc5be8027dd7eb4b26039d76a4f (patch)
tree522b7197c9f8eb452599f481dca2140384b01360 /opcodes/i386-dis.c
parent257385246e4e7790890d2d2927f1ca2efb780a37 (diff)
downloadfsf-binutils-gdb-b6169b206a513cc5be8027dd7eb4b26039d76a4f.zip
fsf-binutils-gdb-b6169b206a513cc5be8027dd7eb4b26039d76a4f.tar.gz
fsf-binutils-gdb-b6169b206a513cc5be8027dd7eb4b26039d76a4f.tar.bz2
gas/
2008-12-20 H.J. Lu <hongjiu.lu@intel.com> * config/tc-i386.c (_i386_insn): Add swap_operand. (parse_insn): Handle ".s". (match_template): Handle swap_operand. * doc/c-i386.texi: Document .s suffix. gas/testsuite/ 2008-12-20 H.J. Lu <hongjiu.lu@intel.com> * gas/i386/i386.exp: Run opts, opts-intel, sse2avx-opts, sse2avx-opts-intel, x86-64-opts, x86-64-opts-intel, x86-64-sse2avx-opts and x86-64-sse2avx-opts-intel. * gas/i386/opts.d: New. * gas/i386/opts-intel.d: Likewise. * gas/i386/opts.s: Likewise. * gas/i386/sse2avx-opts.d: Likewise. * gas/i386/sse2avx-opts-intel.d: Likewise. * gas/i386/x86-64-opts.d: Likewise. * gas/i386/x86-64-opts-intel.d: Likewise. * gas/i386/x86-64-opts.s: Likewise. * gas/i386/x86-64-sse2avx-opts.d: Likewise. * gas/i386/x86-64-sse2avx-opts-intel.d: Likewise. opcodes/ 2008-12-20 H.J. Lu <hongjiu.lu@intel.com> * i386-dis.c (EbS): New. (EvS): Likewise. (EMS): Likewise. (EXqS): Likewise. (EXxS): Likewise. (b_swap_mode): Likewise. (v_swap_mode): Likewise. (q_swap_mode): Likewise. (x_swap_mode): Likewise. (v_mode): Updated. (w_mode): Likewise. (t_mode): Likewise. (xmm_mode): Likewise. (swap_operand): Likewise. (dis386): Use EbS on movB. Use EvS on moveS. (dis386_twobyte): Use EXxS on movapX. (prefix_table): Use EXxS on movups, movupd, movdqu, movdqa, vmovups, vmovdqu, vmovdqa. Use EMS and EXqS on movq. (vex_table): Use EXxS on vmovapX. (vex_len_table): Use EXqS on vmovq. (intel_operand_size): Handle b_swap_mode, v_swap_mode, q_swap_mode and x_swap_mode. (OP_E_register): Handle b_swap_mode and v_swap_mode. (OP_EM): Handle v_swap_mode. (OP_EX): x_swap_mode and q_swap_mode. * i386-gen.c (opcode_modifiers): Add S. * i386-opc.h (S): New. (Modrm): Updated. (i386_opcode_modifier): Add s. * i386-opc.tbl: Add S to movapd, movaps, movdqa, movdqu, movq, movupd, movups, vmovapd, vmovaps, vmovdqa, vmovdqu and vmovq. * i386-tbl.h: Regenerated.
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c83
1 files changed, 62 insertions, 21 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 0724453..50088d0 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -240,7 +240,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define XX { NULL, 0 }
#define Eb { OP_E, b_mode }
+#define EbS { OP_E, b_swap_mode }
#define Ev { OP_E, v_mode }
+#define EvS { OP_E, v_swap_mode }
#define Ed { OP_E, d_mode }
#define Edq { OP_E, dq_mode }
#define Edqw { OP_E, dqw_mode }
@@ -355,12 +357,15 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define XM { OP_XMM, 0 }
#define XMM { OP_XMM, xmm_mode }
#define EM { OP_EM, v_mode }
+#define EMS { OP_EM, v_swap_mode }
#define EMd { OP_EM, d_mode }
#define EMx { OP_EM, x_mode }
#define EXw { OP_EX, w_mode }
#define EXd { OP_EX, d_mode }
#define EXq { OP_EX, q_mode }
+#define EXqS { OP_EX, q_swap_mode }
#define EXx { OP_EX, x_mode }
+#define EXxS { OP_EX, x_swap_mode }
#define EXxmm { OP_EX, xmm_mode }
#define EXxmmq { OP_EX, xmmq_mode }
#define EXymmq { OP_EX, ymmq_mode }
@@ -412,20 +417,28 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
/* byte operand */
#define b_mode 1
+/* byte operand with operand swapped */
+#define b_swap_mode (b_mode + 1)
/* operand size depends on prefixes */
-#define v_mode (b_mode + 1)
+#define v_mode (b_swap_mode + 1)
+/* operand size depends on prefixes with operand swapped */
+#define v_swap_mode (v_mode + 1)
/* word operand */
-#define w_mode (v_mode + 1)
+#define w_mode (v_swap_mode + 1)
/* double word operand */
#define d_mode (w_mode + 1)
/* quad word operand */
#define q_mode (d_mode + 1)
+/* quad word operand with operand swapped */
+#define q_swap_mode (q_mode + 1)
/* ten-byte operand */
-#define t_mode (q_mode + 1)
+#define t_mode (q_swap_mode + 1)
/* 16-byte XMM or 32-byte YMM operand */
#define x_mode (t_mode + 1)
+/* 16-byte XMM or 32-byte YMM operand with operand swapped */
+#define x_swap_mode (x_mode + 1)
/* 16-byte XMM operand */
-#define xmm_mode (x_mode + 1)
+#define xmm_mode (x_swap_mode + 1)
/* 16-byte XMM or quad word operand */
#define xmmq_mode (xmm_mode + 1)
/* 32-byte YMM or quad word operand */
@@ -1458,8 +1471,8 @@ static const struct dis386 dis386[] = {
/* 88 */
{ "movB", { Eb, Gb } },
{ "movS", { Ev, Gv } },
- { "movB", { Gb, Eb } },
- { "movS", { Gv, Ev } },
+ { "movB", { Gb, EbS } },
+ { "movS", { Gv, EvS } },
{ "movD", { Sv, Sw } },
{ MOD_TABLE (MOD_8D) },
{ "movD", { Sw, Sv } },
@@ -1640,7 +1653,7 @@ static const struct dis386 dis386_twobyte[] = {
{ "(bad)", { XX } },
/* 28 */
{ "movapX", { XM, EXx } },
- { "movapX", { EXx, XM } },
+ { "movapX", { EXxS, XM } },
{ PREFIX_TABLE (PREFIX_0F2A) },
{ PREFIX_TABLE (PREFIX_0F2B) },
{ PREFIX_TABLE (PREFIX_0F2C) },
@@ -2413,9 +2426,9 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_0F11 */
{
- { "movups", { EXx, XM } },
+ { "movups", { EXxS, XM } },
{ "movss", { EXd, XM } },
- { "movupd", { EXx, XM } },
+ { "movupd", { EXxS, XM } },
{ "movsd", { EXq, XM } },
},
@@ -2685,9 +2698,9 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_0F7F */
{
- { "movq", { EM, MX } },
- { "movdqu", { EXx, XM } },
- { "movdqa", { EXx, XM } },
+ { "movq", { EMS, MX } },
+ { "movdqu", { EXxS, XM } },
+ { "movdqa", { EXxS, XM } },
{ "(bad)", { XX } },
},
@@ -2743,7 +2756,7 @@ static const struct dis386 prefix_table[][4] = {
{
{ "(bad)", { XX } },
{ "movq2dq",{ XM, MS } },
- { "movq", { EXq, XM } },
+ { "movq", { EXqS, XM } },
{ "movdq2q",{ MX, XS } },
},
@@ -3293,9 +3306,9 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_VEX_11 */
{
- { "vmovups", { EXx, XM } },
+ { "vmovups", { EXxS, XM } },
{ VEX_LEN_TABLE (VEX_LEN_11_P_1) },
- { "vmovupd", { EXx, XM } },
+ { "vmovupd", { EXxS, XM } },
{ VEX_LEN_TABLE (VEX_LEN_11_P_3) },
},
@@ -3718,8 +3731,8 @@ static const struct dis386 prefix_table[][4] = {
/* PREFIX_VEX_7F */
{
{ "(bad)", { XX } },
- { "vmovdqu", { EXx, XM } },
- { "vmovdqa", { EXx, XM } },
+ { "vmovdqu", { EXxS, XM } },
+ { "vmovdqa", { EXxS, XM } },
{ "(bad)", { XX } },
},
@@ -6989,7 +7002,7 @@ static const struct dis386 vex_table[][256] = {
{ "(bad)", { XX } },
/* 28 */
{ "vmovapX", { XM, EXx } },
- { "vmovapX", { EXx, XM } },
+ { "vmovapX", { EXxS, XM } },
{ PREFIX_TABLE (PREFIX_VEX_2A) },
{ MOD_TABLE (MOD_VEX_2B) },
{ PREFIX_TABLE (PREFIX_VEX_2C) },
@@ -8328,7 +8341,7 @@ static const struct dis386 vex_len_table[][2] = {
/* VEX_LEN_D6_P_2 */
{
- { "vmovq", { EXq, XM } },
+ { "vmovq", { EXqS, XM } },
{ "(bad)", { XX } },
},
@@ -10724,6 +10737,14 @@ static char *fgrps[][8] = {
};
static void
+swap_operand (void)
+{
+ mnemonicendp[0] = '.';
+ mnemonicendp[1] = 's';
+ mnemonicendp += 2;
+}
+
+static void
OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
@@ -11351,6 +11372,7 @@ intel_operand_size (int bytemode, int sizeflag)
switch (bytemode)
{
case b_mode:
+ case b_swap_mode:
case dqb_mode:
oappend ("BYTE PTR ");
break;
@@ -11367,6 +11389,7 @@ intel_operand_size (int bytemode, int sizeflag)
}
/* FALLTHRU */
case v_mode:
+ case v_swap_mode:
case dq_mode:
USED_REX (REX_W);
if (rex & REX_W)
@@ -11396,6 +11419,7 @@ intel_operand_size (int bytemode, int sizeflag)
oappend ("DWORD PTR ");
break;
case q_mode:
+ case q_swap_mode:
oappend ("QWORD PTR ");
break;
case m_mode:
@@ -11415,6 +11439,7 @@ intel_operand_size (int bytemode, int sizeflag)
oappend ("TBYTE PTR ");
break;
case x_mode:
+ case x_swap_mode:
if (need_vex)
{
switch (vex.length)
@@ -11485,9 +11510,14 @@ OP_E_register (int bytemode, int sizeflag)
if ((rex & REX_B))
reg += 8;
+ if ((sizeflag & SUFFIX_ALWAYS)
+ && (bytemode == b_swap_mode || bytemode == v_swap_mode))
+ swap_operand ();
+
switch (bytemode)
{
case b_mode:
+ case b_swap_mode:
USED_REX (0);
if (rex)
names = names8rex;
@@ -11516,6 +11546,7 @@ OP_E_register (int bytemode, int sizeflag)
bytemode = v_mode;
/* FALLTHRU */
case v_mode:
+ case v_swap_mode:
case dq_mode:
case dqb_mode:
case dqd_mode:
@@ -11523,7 +11554,9 @@ OP_E_register (int bytemode, int sizeflag)
USED_REX (REX_W);
if (rex & REX_W)
names = names64;
- else if ((sizeflag & DFLAG) || bytemode != v_mode)
+ else if ((sizeflag & DFLAG)
+ || (bytemode != v_mode
+ && bytemode != v_swap_mode))
names = names32;
else
names = names16;
@@ -12535,7 +12568,8 @@ OP_EM (int bytemode, int sizeflag)
{
if (modrm.mod != 3)
{
- if (intel_syntax && bytemode == v_mode)
+ if (intel_syntax
+ && (bytemode == v_mode || bytemode == v_swap_mode))
{
bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
used_prefixes |= (prefixes & PREFIX_DATA);
@@ -12544,6 +12578,9 @@ OP_EM (int bytemode, int sizeflag)
return;
}
+ if ((sizeflag & SUFFIX_ALWAYS) && bytemode == v_swap_mode)
+ swap_operand ();
+
/* Skip mod/rm byte. */
MODRM_CHECK;
codep++;
@@ -12614,6 +12651,10 @@ OP_EX (int bytemode, int sizeflag)
else
add = 0;
+ if ((sizeflag & SUFFIX_ALWAYS)
+ && (bytemode == x_swap_mode || bytemode == q_swap_mode))
+ swap_operand ();
+
/* Skip mod/rm byte. */
MODRM_CHECK;
codep++;