summaryrefslogtreecommitdiffstats
path: root/gas/config/tc-i386.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 /gas/config/tc-i386.c
parent257385246e4e7790890d2d2927f1ca2efb780a37 (diff)
downloadppe42-binutils-b6169b206a513cc5be8027dd7eb4b26039d76a4f.tar.gz
ppe42-binutils-b6169b206a513cc5be8027dd7eb4b26039d76a4f.zip
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 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index f0b374d96a..d74c1c664d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -279,6 +279,9 @@ struct _i386_insn
sib_byte sib;
drex_byte drex;
vex_prefix vex;
+
+ /* Swap operand in encoding. */
+ unsigned int swap_operand : 1;
};
typedef struct _i386_insn i386_insn;
@@ -2908,6 +2911,7 @@ parse_insn (char *line, char *mnemonic)
char *mnem_p;
int supported;
const template *t;
+ char *dot_p = NULL;
/* Non-zero if we found a prefix only acceptable with string insns. */
const char *expecting_string_instruction = NULL;
@@ -2917,6 +2921,8 @@ parse_insn (char *line, char *mnemonic)
mnem_p = mnemonic;
while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
{
+ if (*mnem_p == '.')
+ dot_p = mnem_p;
mnem_p++;
if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
{
@@ -2988,8 +2994,24 @@ parse_insn (char *line, char *mnemonic)
break;
}
+ if (!current_templates && dot_p)
+ {
+ if (mnem_p - 2 == dot_p)
+ {
+ /* Check if we should swap operand in encoding. */
+ if (dot_p[1] == 's')
+ i.swap_operand = 1;
+ else
+ goto check_suffix;
+ mnem_p = dot_p;
+ *dot_p = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ }
+ }
+
if (!current_templates)
{
+check_suffix:
/* See if we can get a match by trimming off a suffix. */
switch (mnem_p[-1])
{
@@ -3712,6 +3734,16 @@ match_template (void)
&& operand_type_equal (&i.types [0], &acc32)
&& operand_type_equal (&i.types [1], &acc32))
continue;
+ if (i.swap_operand)
+ {
+ /* If we swap operand in encoding, we either match
+ the next one or reverse direction of operands. */
+ if (t->opcode_modifier.s)
+ continue;
+ else if (t->opcode_modifier.d)
+ goto check_reverse;
+ }
+
case 3:
case 4:
case 5:
@@ -3728,6 +3760,7 @@ match_template (void)
if (!t->opcode_modifier.d && !t->opcode_modifier.floatd)
continue;
+check_reverse:
/* Try reversing direction of operands. */
overlap0 = operand_type_and (i.types[0], operand_types[1]);
overlap1 = operand_type_and (i.types[1], operand_types[0]);
OpenPOWER on IntegriCloud