diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2008-12-20 17:40:51 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2008-12-20 17:40:51 +0000 |
commit | b6169b206a513cc5be8027dd7eb4b26039d76a4f (patch) | |
tree | 522b7197c9f8eb452599f481dca2140384b01360 /opcodes/i386-dis.c | |
parent | 257385246e4e7790890d2d2927f1ca2efb780a37 (diff) | |
download | gdb-b6169b206a513cc5be8027dd7eb4b26039d76a4f.zip gdb-b6169b206a513cc5be8027dd7eb4b26039d76a4f.tar.gz 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.c | 83 |
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++; |