[PATCH v3 4/7] x86-64: further re-work insn/suffix recognition to also cover MOVSL
Jan Beulich
jbeulich@suse.com
Wed Oct 5 07:24:20 GMT 2022
PR gas/29524
In order to make MOVSL{,Q} behave similarly to MOVSB{W,L,Q} and
MOVSW{L,Q} we need to defer parse_insn()'s emitting of errors unrelated
to prefix parsing. Utilize i.error just like match_template() does.
---
v3: Re-base over changes to earlier patches (incl use of Pass2).
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -236,6 +236,8 @@ enum i386_error
unsupported_with_intel_mnemonic,
unsupported_syntax,
unsupported,
+ unsupported_on_arch,
+ unsupported_64bit,
invalid_sib_address,
invalid_vsib_address,
invalid_vector_register_set,
@@ -4849,6 +4851,15 @@ md_assemble (char *line)
{
if (pass1_mnem != NULL)
goto match_error;
+ if (i.error != no_error)
+ {
+ gas_assert (current_templates != NULL);
+ if (current_templates->start->opcode_modifier.pass2 && !i.suffix)
+ goto no_match;
+ /* No point in trying a 2nd pass - it'll only find the same suffix
+ again. */
+ goto match_error;
+ }
return;
}
if (current_templates->start->opcode_modifier.pass2)
@@ -4948,12 +4959,21 @@ md_assemble (char *line)
{
line = copy;
copy = NULL;
+ no_match:
pass1_err = i.error;
pass1_mnem = current_templates->start->name;
goto retry;
}
- free (copy);
+
+ /* If a non-/only-64bit template (group) was found in pass 1, and if
+ _some_ template (group) was found in pass 2, squash pass 1's
+ error. */
+ if (pass1_err == unsupported_64bit)
+ pass1_mnem = NULL;
+
match_error:
+ free (copy);
+
switch (pass1_mnem ? pass1_err : i.error)
{
default:
@@ -4986,6 +5006,17 @@ md_assemble (char *line)
as_bad (_("unsupported instruction `%s'"),
pass1_mnem ? pass1_mnem : current_templates->start->name);
return;
+ case unsupported_on_arch:
+ as_bad (_("`%s' is not supported on `%s%s'"),
+ pass1_mnem ? pass1_mnem : current_templates->start->name,
+ cpu_arch_name ? cpu_arch_name : default_arch,
+ cpu_sub_arch_name ? cpu_sub_arch_name : "");
+ return;
+ case unsupported_64bit:
+ as_bad (_("`%s' is %s supported in 64-bit mode"),
+ pass1_mnem ? pass1_mnem : current_templates->start->name,
+ flag_code == CODE_64BIT ? _("not") : _("only"));
+ return;
case invalid_sib_address:
err_msg = _("invalid SIB address");
break;
@@ -5601,16 +5632,13 @@ parse_insn (const char *line, char *mnem
return l;
}
- if (!(supported & CPU_FLAGS_64BIT_MATCH))
- as_bad (flag_code == CODE_64BIT
- ? _("`%s' is not supported in 64-bit mode")
- : _("`%s' is only supported in 64-bit mode"),
- current_templates->start->name);
- else
- as_bad (_("`%s' is not supported on `%s%s'"),
- current_templates->start->name,
- cpu_arch_name ? cpu_arch_name : default_arch,
- cpu_sub_arch_name ? cpu_sub_arch_name : "");
+ if (pass1)
+ {
+ if (supported & CPU_FLAGS_64BIT_MATCH)
+ i.error = unsupported_on_arch;
+ else
+ i.error = unsupported_64bit;
+ }
return NULL;
}
--- a/gas/testsuite/gas/i386/movs.s
+++ b/gas/testsuite/gas/i386/movs.s
@@ -30,4 +30,10 @@ movs:
.ifdef x86_64
movswq %ax,%rax
movswq (%rax),%rax
+
+ movsl %eax,%rax
+ movsl (%rax),%rax
+
+ movslq %eax,%rax
+ movslq (%rax),%rax
.endif
--- a/gas/testsuite/gas/i386/movx64.l
+++ b/gas/testsuite/gas/i386/movx64.l
@@ -241,6 +241,46 @@
[ ]*[1-9][0-9]*[ ]+movswq %eax, %rcx
[ ]*[1-9][0-9]*[ ]+movswq %rax, %rcx
[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movsl %al, %cl
+[ ]*[1-9][0-9]*[ ]+movsl %ax, %cl
+[ ]*[1-9][0-9]*[ ]+movsl %eax, %cl
+[ ]*[1-9][0-9]*[ ]+movsl %rax, %cl
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movsl %al, %cx
+[ ]*[1-9][0-9]*[ ]+movsl %ax, %cx
+[ ]*[1-9][0-9]*[ ]+movsl %eax, %cx
+[ ]*[1-9][0-9]*[ ]+movsl %rax, %cx
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movsl %al, %ecx
+[ ]*[1-9][0-9]*[ ]+movsl %ax, %ecx
+[ ]*[1-9][0-9]*[ ]+movsl %eax, %ecx
+[ ]*[1-9][0-9]*[ ]+movsl %rax, %ecx
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movsl %al, %rcx
+[ ]*[1-9][0-9]*[ ]+movsl %ax, %rcx
+[ ]*[1-9][0-9]* \?\?\?\? 4863C8[ ]+movsl %eax, %rcx
+[ ]*[1-9][0-9]*[ ]+movsl %rax, %rcx
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movslq %al, %cl
+[ ]*[1-9][0-9]*[ ]+movslq %ax, %cl
+[ ]*[1-9][0-9]*[ ]+movslq %eax, %cl
+[ ]*[1-9][0-9]*[ ]+movslq %rax, %cl
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movslq %al, %cx
+[ ]*[1-9][0-9]*[ ]+movslq %ax, %cx
+[ ]*[1-9][0-9]*[ ]+movslq %eax, %cx
+[ ]*[1-9][0-9]*[ ]+movslq %rax, %cx
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movslq %al, %ecx
+[ ]*[1-9][0-9]*[ ]+movslq %ax, %ecx
+[ ]*[1-9][0-9]*[ ]+movslq %eax, %ecx
+[ ]*[1-9][0-9]*[ ]+movslq %rax, %ecx
+[ ]*[1-9][0-9]*[ ]*
+[ ]*[1-9][0-9]*[ ]+movslq %al, %rcx
+[ ]*[1-9][0-9]*[ ]+movslq %ax, %rcx
+[ ]*[1-9][0-9]* \?\?\?\? 4863C8[ ]+movslq %eax, %rcx
+[ ]*[1-9][0-9]*[ ]+movslq %rax, %rcx
+[ ]*[1-9][0-9]*[ ]*
[ ]*[1-9][0-9]*[ ]+movzx:
[ ]*[1-9][0-9]*[ ]+movzx %al, %cl
[ ]*[1-9][0-9]*[ ]+movzx %ax, %cl
--- a/gas/testsuite/gas/i386/movx64.s
+++ b/gas/testsuite/gas/i386/movx64.s
@@ -241,6 +241,46 @@ movsx:
movswq %eax, %rcx
movswq %rax, %rcx
+ movsl %al, %cl
+ movsl %ax, %cl
+ movsl %eax, %cl
+ movsl %rax, %cl
+
+ movsl %al, %cx
+ movsl %ax, %cx
+ movsl %eax, %cx
+ movsl %rax, %cx
+
+ movsl %al, %ecx
+ movsl %ax, %ecx
+ movsl %eax, %ecx
+ movsl %rax, %ecx
+
+ movsl %al, %rcx
+ movsl %ax, %rcx
+ movsl %eax, %rcx
+ movsl %rax, %rcx
+
+ movslq %al, %cl
+ movslq %ax, %cl
+ movslq %eax, %cl
+ movslq %rax, %cl
+
+ movslq %al, %cx
+ movslq %ax, %cx
+ movslq %eax, %cx
+ movslq %rax, %cx
+
+ movslq %al, %ecx
+ movslq %ax, %ecx
+ movslq %eax, %ecx
+ movslq %rax, %ecx
+
+ movslq %al, %rcx
+ movslq %ax, %rcx
+ movslq %eax, %rcx
+ movslq %rax, %rcx
+
movzx:
movzx %al, %cl
movzx %ax, %cl
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -164,9 +164,7 @@ movbe, 0x0f38f0, None, CpuMovbe, D|Modrm
// Move with sign extend.
movsb, 0xfbe, None, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf|Pass2, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
movsw, 0xfbf, None, Cpu386, Modrm|No_bSuf|No_wSuf|No_sSuf|No_ldSuf|Pass2, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
-// "movslq" must not be converted into "movsl" to avoid conflict with the
-// "movsl" string move instruction.
-movslq, 0x63, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Size64, { Reg32|Dword|Unspecified|BaseIndex, Reg64 }
+movsl, 0x63, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|Pass2, { Reg32|Unspecified|BaseIndex, Reg64 }
movsx, 0xfbe, None, Cpu386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
movsx, 0x63, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
movsxd, 0x63, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
More information about the Binutils
mailing list