From: "H.J. Lu" <hjl.tools@gmail.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: Binutils <binutils@sourceware.org>
Subject: Re: [PATCH 5/7] x86: re-work insn/suffix recognition
Date: Wed, 17 Aug 2022 13:29:12 -0700 [thread overview]
Message-ID: <CAMe9rOqCJXZe2nO6vCKRhWm2SuC1x3T-3ZLEdDQc8FB5TuHTJw@mail.gmail.com> (raw)
In-Reply-To: <eadc6f65-ff8b-baee-14e3-5c5c01234452@suse.com>
On Tue, Aug 16, 2022 at 12:32 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> x86: re-work insn/suffix recognition
>
> Having templates with a suffix explicitly present has always been
> quirky. Introduce a 2nd matching pass in case the 1st one couldn't find
I don't like the second pass. What problem does it solve?
> a suitable template _and_ didn't itself already need to trim off a
> suffix to find a match at all. This requires error reporting adjustments
> (albeit luckily fewer than I was afraid might be necessary), as errors
> previously reported during matching now need deferring until after the
> 2nd pass (because, obviously, we must not emit any error if the 2nd pass
> succeeds).
>
> Note that with the dropped CMPSD and MOVSD Intel Syntax string insn
> templates, mixed IsString/non-IsString template groups cannot occur
> anymore. With that maybe_adjust_templates() becomes unnecessary (and is
> hence being removed).
>
> Note further that while the additions to the intel16 testcase aren't
> really proper Intel syntax, we've been permitting all of those except
> for the MOVD variant. The test therefore is to avoid re-introducing such
> an inconsistency.
> ---
> To limit code churn I'm using "goto" for the retry loop, but I'd be
> happy to make this a proper loop either right here or in a follow-on
> change doing just the necessary re-indentation.
>
> The "too many memory references" errors which are being deleted weren't
> fully consistent anyway - even the majority of IsString insns accepts
> only a single memory operand. If we want to retain that, it would need
> re-introducing in md_assemble(), latching the error into i.error just
> like match_template() does.
>
> Why is "MOVQ $imm64, %reg64" being optimized but "MOVABS $imm64, %reg64"
> is not?
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -297,9 +297,6 @@ struct _i386_insn
> explicit segment overrides are given. */
> const reg_entry *seg[2];
>
> - /* Copied first memory operand string, for re-checking. */
> - char *memop1_string;
> -
> /* PREFIX holds all the given prefix opcodes (usually null).
> PREFIXES is the number of prefix opcodes. */
> unsigned int prefixes;
> @@ -4273,7 +4270,20 @@ optimize_encoding (void)
> movq $imm31, %r64 -> movl $imm31, %r32
> movq $imm32, %r64 -> movl $imm32, %r32
> */
> - i.tm.opcode_modifier.norex64 = 1;
> + i.tm.opcode_modifier.size = SIZE32;
> + if (i.imm_operands)
> + {
> + i.types[0].bitfield.imm32 = 1;
> + i.types[0].bitfield.imm32s = 0;
> + i.types[0].bitfield.imm64 = 0;
> + }
> + else
> + {
> + i.types[0].bitfield.dword = 1;
> + i.types[0].bitfield.qword = 0;
> + }
> + i.types[1].bitfield.dword = 1;
> + i.types[1].bitfield.qword = 0;
> if (i.tm.base_opcode == 0xb8 || (i.tm.base_opcode | 1) == 0xc7)
> {
> /* Handle
> @@ -4283,11 +4293,6 @@ optimize_encoding (void)
> i.tm.operand_types[0].bitfield.imm32 = 1;
> i.tm.operand_types[0].bitfield.imm32s = 0;
> i.tm.operand_types[0].bitfield.imm64 = 0;
> - i.types[0].bitfield.imm32 = 1;
> - i.types[0].bitfield.imm32s = 0;
> - i.types[0].bitfield.imm64 = 0;
> - i.types[1].bitfield.dword = 1;
> - i.types[1].bitfield.qword = 0;
> if ((i.tm.base_opcode | 1) == 0xc7)
> {
> /* Handle
> @@ -4819,10 +4824,17 @@ void
> md_assemble (char *line)
> {
> unsigned int j;
> - char mnemonic[MAX_MNEM_SIZE], mnem_suffix;
> + char mnemonic[MAX_MNEM_SIZE], mnem_suffix, *copy;
> + const char *pass1_mnem = NULL;
> + enum i386_error pass1_err = 0;
> const insn_template *t;
>
> + /* Make a copy of the full line in case we need to retry. */
> + copy = xstrdup (line);
> +
> /* Initialize globals. */
> + current_templates = NULL;
> + retry:
> memset (&i, '\0', sizeof (i));
> i.rounding.type = rc_none;
> for (j = 0; j < MAX_OPERANDS; j++)
> @@ -4837,15 +4849,21 @@ md_assemble (char *line)
>
> line = parse_insn (line, mnemonic);
> if (line == NULL)
> - return;
> + {
> + if (!copy)
> + goto match_error;
> + free (copy);
> + return;
> + }
> mnem_suffix = i.suffix;
>
> line = parse_operands (line, mnemonic);
> this_operand = -1;
> - xfree (i.memop1_string);
> - i.memop1_string = NULL;
> if (line == NULL)
> - return;
> + {
> + free (copy);
> + return;
> + }
>
> /* Now we've parsed the mnemonic into a set of templates, and have the
> operands at hand. */
> @@ -4921,7 +4939,97 @@ md_assemble (char *line)
> with the template operand types. */
>
> if (!(t = match_template (mnem_suffix)))
> - return;
> + {
> + const char *err_msg;
> +
> + if (!mnem_suffix)
> + {
> + pass1_err = i.error;
> + pass1_mnem = current_templates->start->name;
> + line = copy;
> + copy = NULL;
> + goto retry;
> + }
> + free (copy);
> + match_error:
> + switch (pass1_mnem ? pass1_err : i.error)
> + {
> + default:
> + abort ();
> + case operand_size_mismatch:
> + err_msg = _("operand size mismatch");
> + break;
> + case operand_type_mismatch:
> + err_msg = _("operand type mismatch");
> + break;
> + case register_type_mismatch:
> + err_msg = _("register type mismatch");
> + break;
> + case number_of_operands_mismatch:
> + err_msg = _("number of operands mismatch");
> + break;
> + case invalid_instruction_suffix:
> + err_msg = _("invalid instruction suffix");
> + break;
> + case bad_imm4:
> + err_msg = _("constant doesn't fit in 4 bits");
> + break;
> + case unsupported_with_intel_mnemonic:
> + err_msg = _("unsupported with Intel mnemonic");
> + break;
> + case unsupported_syntax:
> + err_msg = _("unsupported syntax");
> + break;
> + case unsupported:
> + as_bad (_("unsupported instruction `%s'"),
> + pass1_mnem ? pass1_mnem : current_templates->start->name);
> + return;
> + case invalid_sib_address:
> + err_msg = _("invalid SIB address");
> + break;
> + case invalid_vsib_address:
> + err_msg = _("invalid VSIB address");
> + break;
> + case invalid_vector_register_set:
> + err_msg = _("mask, index, and destination registers must be distinct");
> + break;
> + case invalid_tmm_register_set:
> + err_msg = _("all tmm registers must be distinct");
> + break;
> + case invalid_dest_and_src_register_set:
> + err_msg = _("destination and source registers must be distinct");
> + break;
> + case unsupported_vector_index_register:
> + err_msg = _("unsupported vector index register");
> + break;
> + case unsupported_broadcast:
> + err_msg = _("unsupported broadcast");
> + break;
> + case broadcast_needed:
> + err_msg = _("broadcast is needed for operand of such type");
> + break;
> + case unsupported_masking:
> + err_msg = _("unsupported masking");
> + break;
> + case mask_not_on_destination:
> + err_msg = _("mask not on destination operand");
> + break;
> + case no_default_mask:
> + err_msg = _("default mask isn't allowed");
> + break;
> + case unsupported_rc_sae:
> + err_msg = _("unsupported static rounding/sae");
> + break;
> + case invalid_register_operand:
> + err_msg = _("invalid register operand");
> + break;
> + }
> + as_bad (_("%s for `%s'"), err_msg,
> + pass1_mnem ? pass1_mnem : current_templates->start->name);
> + return;
> + }
> +
> + free (copy);
>
> if (sse_check != check_none
> /* The opcode space check isn't strictly needed; it's there only to
> @@ -5223,6 +5331,7 @@ parse_insn (char *line, char *mnemonic)
> char *l = line;
> char *token_start = l;
> char *mnem_p;
> + bool pass1 = !current_templates;
> int supported;
> const insn_template *t;
> char *dot_p = NULL;
> @@ -5392,8 +5501,10 @@ parse_insn (char *line, char *mnemonic)
> current_templates = (const templates *) str_hash_find (op_hash, mnemonic);
> }
>
> - if (!current_templates)
> + if (!current_templates || !pass1)
> {
> + current_templates = NULL;
> +
> check_suffix:
> if (mnem_p > mnemonic)
> {
> @@ -5441,7 +5552,8 @@ parse_insn (char *line, char *mnemonic)
>
> if (!current_templates)
> {
> - as_bad (_("no such instruction: `%s'"), token_start);
> + if (pass1)
> + as_bad (_("no such instruction: `%s'"), token_start);
> return NULL;
> }
> }
> @@ -6851,81 +6963,7 @@ match_template (char mnem_suffix)
> if (t == current_templates->end)
> {
> /* We found no match. */
> - const char *err_msg;
> - switch (specific_error)
> - {
> - default:
> - abort ();
> - case operand_size_mismatch:
> - err_msg = _("operand size mismatch");
> - break;
> - case operand_type_mismatch:
> - err_msg = _("operand type mismatch");
> - break;
> - case register_type_mismatch:
> - err_msg = _("register type mismatch");
> - break;
> - case number_of_operands_mismatch:
> - err_msg = _("number of operands mismatch");
> - break;
> - case invalid_instruction_suffix:
> - err_msg = _("invalid instruction suffix");
> - break;
> - case bad_imm4:
> - err_msg = _("constant doesn't fit in 4 bits");
> - break;
> - case unsupported_with_intel_mnemonic:
> - err_msg = _("unsupported with Intel mnemonic");
> - break;
> - case unsupported_syntax:
> - err_msg = _("unsupported syntax");
> - break;
> - case unsupported:
> - as_bad (_("unsupported instruction `%s'"),
> - current_templates->start->name);
> - return NULL;
> - case invalid_sib_address:
> - err_msg = _("invalid SIB address");
> - break;
> - case invalid_vsib_address:
> - err_msg = _("invalid VSIB address");
> - break;
> - case invalid_vector_register_set:
> - err_msg = _("mask, index, and destination registers must be distinct");
> - break;
> - case invalid_tmm_register_set:
> - err_msg = _("all tmm registers must be distinct");
> - break;
> - case invalid_dest_and_src_register_set:
> - err_msg = _("destination and source registers must be distinct");
> - break;
> - case unsupported_vector_index_register:
> - err_msg = _("unsupported vector index register");
> - break;
> - case unsupported_broadcast:
> - err_msg = _("unsupported broadcast");
> - break;
> - case broadcast_needed:
> - err_msg = _("broadcast is needed for operand of such type");
> - break;
> - case unsupported_masking:
> - err_msg = _("unsupported masking");
> - break;
> - case mask_not_on_destination:
> - err_msg = _("mask not on destination operand");
> - break;
> - case no_default_mask:
> - err_msg = _("default mask isn't allowed");
> - break;
> - case unsupported_rc_sae:
> - err_msg = _("unsupported static rounding/sae");
> - break;
> - case invalid_register_operand:
> - err_msg = _("invalid register operand");
> - break;
> - }
> - as_bad (_("%s for `%s'"), err_msg,
> - current_templates->start->name);
> + i.error = specific_error;
> return NULL;
> }
>
> @@ -11334,49 +11372,6 @@ RC_SAE_immediate (const char *imm_start)
> return 1;
> }
>
> -/* Only string instructions can have a second memory operand, so
> - reduce current_templates to just those if it contains any. */
> -static int
> -maybe_adjust_templates (void)
> -{
> - const insn_template *t;
> -
> - gas_assert (i.mem_operands == 1);
> -
> - for (t = current_templates->start; t < current_templates->end; ++t)
> - if (t->opcode_modifier.isstring)
> - break;
> -
> - if (t < current_templates->end)
> - {
> - static templates aux_templates;
> - bool recheck;
> -
> - aux_templates.start = t;
> - for (; t < current_templates->end; ++t)
> - if (!t->opcode_modifier.isstring)
> - break;
> - aux_templates.end = t;
> -
> - /* Determine whether to re-check the first memory operand. */
> - recheck = (aux_templates.start != current_templates->start
> - || t != current_templates->end);
> -
> - current_templates = &aux_templates;
> -
> - if (recheck)
> - {
> - i.mem_operands = 0;
> - if (i.memop1_string != NULL
> - && i386_index_check (i.memop1_string) == 0)
> - return 0;
> - i.mem_operands = 1;
> - }
> - }
> -
> - return 1;
> -}
> -
> static INLINE bool starts_memory_operand (char c)
> {
> return ISDIGIT (c)
> @@ -11527,17 +11522,6 @@ i386_att_operand (char *operand_string)
> char *displacement_string_end;
>
> do_memory_reference:
> - if (i.mem_operands == 1 && !maybe_adjust_templates ())
> - return 0;
> - if ((i.mem_operands == 1
> - && !current_templates->start->opcode_modifier.isstring)
> - || i.mem_operands == 2)
> - {
> - as_bad (_("too many memory references for `%s'"),
> - current_templates->start->name);
> - return 0;
> - }
> -
> /* Check for base index form. We detect the base index form by
> looking for an ')' at the end of the operand, searching
> for the '(' matching it, and finding a REGISTER_PREFIX or ','
> @@ -11737,8 +11721,6 @@ i386_att_operand (char *operand_string)
> if (i386_index_check (operand_string) == 0)
> return 0;
> i.flags[this_operand] |= Operand_Mem;
> - if (i.mem_operands == 0)
> - i.memop1_string = xstrdup (operand_string);
> i.mem_operands++;
> }
> else
> --- a/gas/config/tc-i386-intel.c
> +++ b/gas/config/tc-i386-intel.c
> @@ -993,10 +993,7 @@ i386_intel_operand (char *operand_string
> || intel_state.is_mem)
> {
> /* Memory operand. */
> - if (i.mem_operands == 1 && !maybe_adjust_templates ())
> - return 0;
> - if ((int) i.mem_operands
> - >= 2 - !current_templates->start->opcode_modifier.isstring)
> + if (i.mem_operands)
> {
> /* Handle
>
> @@ -1041,10 +1038,6 @@ i386_intel_operand (char *operand_string
> }
> }
> }
> -
> - as_bad (_("too many memory references for `%s'"),
> - current_templates->start->name);
> - return 0;
> }
>
> /* Swap base and index in 16-bit memory operands like
> @@ -1158,8 +1151,6 @@ i386_intel_operand (char *operand_string
> return 0;
>
> i.flags[this_operand] |= Operand_Mem;
> - if (i.mem_operands == 0)
> - i.memop1_string = xstrdup (operand_string);
> ++i.mem_operands;
> }
> else
> --- a/gas/testsuite/gas/i386/code16.s
> +++ b/gas/testsuite/gas/i386/code16.s
> @@ -1,9 +1,9 @@
> .text
> .code16
> - rep; movsd
> - rep; cmpsd
> - rep movsd %ds:(%si),%es:(%di)
> - rep cmpsd %es:(%di),%ds:(%si)
> + rep; movsl
> + rep; cmpsl
> + rep movsl %ds:(%si),%es:(%di)
> + rep cmpsl %es:(%di),%ds:(%si)
>
> mov %cr2, %ecx
> mov %ecx, %cr2
> --- a/gas/testsuite/gas/i386/i386.exp
> +++ b/gas/testsuite/gas/i386/i386.exp
> @@ -73,6 +73,7 @@ if [gas_32_check] then {
> run_dump_test "amd"
> run_dump_test "katmai"
> run_dump_test "jump"
> + run_dump_test "movs32"
> run_dump_test "movz32"
> run_dump_test "relax-1"
> run_dump_test "relax-2"
> @@ -806,6 +807,7 @@ if [gas_64_check] then {
> run_dump_test "x86-64-segovr"
> run_list_test "x86-64-inval-seg" "-al"
> run_dump_test "x86-64-branch"
> + run_dump_test "movs64"
> run_dump_test "movz64"
> run_dump_test "x86-64-relax-1"
> run_dump_test "svme64"
> --- a/gas/testsuite/gas/i386/intel16.d
> +++ b/gas/testsuite/gas/i386/intel16.d
> @@ -20,4 +20,12 @@ Disassembly of section .text:
> 2c: 8d 02 [ ]*lea \(%bp,%si\),%ax
> 2e: 8d 01 [ ]*lea \(%bx,%di\),%ax
> 30: 8d 03 [ ]*lea \(%bp,%di\),%ax
> - ...
> +[ ]*[0-9a-f]+: 67 f7 13[ ]+notw[ ]+\(%ebx\)
> +[ ]*[0-9a-f]+: 66 f7 17[ ]+notl[ ]+\(%bx\)
> +[ ]*[0-9a-f]+: 67 0f 1f 03[ ]+nopw[ ]+\(%ebx\)
> +[ ]*[0-9a-f]+: 66 0f 1f 07[ ]+nopl[ ]+\(%bx\)
> +[ ]*[0-9a-f]+: 67 83 03 05[ ]+addw[ ]+\$0x5,\(%ebx\)
> +[ ]*[0-9a-f]+: 66 83 07 05[ ]+addl[ ]+\$0x5,\(%bx\)
> +[ ]*[0-9a-f]+: 67 c7 03 05 00[ ]+movw[ ]+\$0x5,\(%ebx\)
> +[ ]*[0-9a-f]+: 66 c7 07 05 00 00 00[ ]+movl[ ]+\$0x5,\(%bx\)
> +#pass
> --- a/gas/testsuite/gas/i386/intel16.s
> +++ b/gas/testsuite/gas/i386/intel16.s
> @@ -18,4 +18,14 @@
> lea ax, [di][bx]
> lea ax, [di][bp]
>
> - .p2align 4,0
> + notw [ebx]
> + notd [bx]
> +
> + nopw [ebx]
> + nopd [bx]
> +
> + addw [ebx], 5
> + addd [bx], 5
> +
> + movw [ebx], 5
> + movd [bx], 5
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/movs.s
> @@ -0,0 +1,33 @@
> + .text
> +movs:
> + movsb %al,%ax
> + movsb (%eax),%ax
> + movsb %al,%eax
> + movsb (%eax),%eax
> +.ifdef x86_64
> + movsb %al,%rax
> + movsb (%rax),%rax
> +.endif
> +
> + movsbw %al,%ax
> + movsbw (%eax),%ax
> + movsbl %al,%eax
> + movsbl (%eax),%eax
> +.ifdef x86_64
> + movsbq %al,%rax
> + movsbq (%rax),%rax
> +.endif
> +
> + movsw %ax,%eax
> + movsw (%eax),%eax
> +.ifdef x86_64
> + movsw %ax,%rax
> + movsw (%rax),%rax
> +.endif
> +
> + movswl %ax,%eax
> + movswl (%eax),%eax
> +.ifdef x86_64
> + movswq %ax,%rax
> + movswq (%rax),%rax
> +.endif
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/movs32.d
> @@ -0,0 +1,22 @@
> +#objdump: -dw
> +#source: movs.s
> +#name: x86 mov with sign-extend (32-bit object)
> +
> +.*: +file format .*
> +
> +Disassembly of section .text:
> +
> +0+ <movs>:
> +[ ]*[a-f0-9]+: 66 0f be c0 * movsbw %al,%ax
> +[ ]*[a-f0-9]+: 66 0f be 00 * movsbw \(%eax\),%ax
> +[ ]*[a-f0-9]+: 0f be c0 * movsbl %al,%eax
> +[ ]*[a-f0-9]+: 0f be 00 * movsbl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 66 0f be c0 * movsbw %al,%ax
> +[ ]*[a-f0-9]+: 66 0f be 00 * movsbw \(%eax\),%ax
> +[ ]*[a-f0-9]+: 0f be c0 * movsbl %al,%eax
> +[ ]*[a-f0-9]+: 0f be 00 * movsbl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 0f bf c0 * movswl %ax,%eax
> +[ ]*[a-f0-9]+: 0f bf 00 * movswl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 0f bf c0 * movswl %ax,%eax
> +[ ]*[a-f0-9]+: 0f bf 00 * movswl \(%eax\),%eax
> +#pass
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/movs64.d
> @@ -0,0 +1,30 @@
> +#objdump: -dw
> +#source: movs.s
> +#name: x86 mov with sign-extend (64-bit object)
> +
> +.*: +file format .*
> +
> +Disassembly of section .text:
> +
> +0+ <movs>:
> +[ ]*[a-f0-9]+: 66 0f be c0 * movsbw %al,%ax
> +[ ]*[a-f0-9]+: 67 66 0f be 00 * movsbw \(%eax\),%ax
> +[ ]*[a-f0-9]+: 0f be c0 * movsbl %al,%eax
> +[ ]*[a-f0-9]+: 67 0f be 00 * movsbl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 48 0f be c0 * movsbq %al,%rax
> +[ ]*[a-f0-9]+: 48 0f be 00 * movsbq \(%rax\),%rax
> +[ ]*[a-f0-9]+: 66 0f be c0 * movsbw %al,%ax
> +[ ]*[a-f0-9]+: 67 66 0f be 00 * movsbw \(%eax\),%ax
> +[ ]*[a-f0-9]+: 0f be c0 * movsbl %al,%eax
> +[ ]*[a-f0-9]+: 67 0f be 00 * movsbl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 48 0f be c0 * movsbq %al,%rax
> +[ ]*[a-f0-9]+: 48 0f be 00 * movsbq \(%rax\),%rax
> +[ ]*[a-f0-9]+: 0f bf c0 * movswl %ax,%eax
> +[ ]*[a-f0-9]+: 67 0f bf 00 * movswl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 48 0f bf c0 * movswq %ax,%rax
> +[ ]*[a-f0-9]+: 48 0f bf 00 * movswq \(%rax\),%rax
> +[ ]*[a-f0-9]+: 0f bf c0 * movswl %ax,%eax
> +[ ]*[a-f0-9]+: 67 0f bf 00 * movswl \(%eax\),%eax
> +[ ]*[a-f0-9]+: 48 0f bf c0 * movswq %ax,%rax
> +[ ]*[a-f0-9]+: 48 0f bf 00 * movswq \(%rax\),%rax
> +#pass
> --- a/gas/testsuite/gas/i386/movx16.l
> +++ b/gas/testsuite/gas/i386/movx16.l
> @@ -41,11 +41,11 @@
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %cl
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cl
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %cx
> +[ ]*[1-9][0-9]* \?\?\?\? 0FBEC8[ ]+movsb %al, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cx
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 660FBEC8[ ]+movsb %al, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> @@ -82,7 +82,7 @@
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %cx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movsw %al, %ecx
> -[ ]*[1-9][0-9]*[ ]+movsw %ax, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 660FBFC8[ ]+movsw %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movswl %al, %cl
> --- a/gas/testsuite/gas/i386/movx32.l
> +++ b/gas/testsuite/gas/i386/movx32.l
> @@ -41,11 +41,11 @@
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %cl
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cl
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %cx
> +[ ]*[1-9][0-9]* \?\?\?\? 660FBEC8[ ]+movsb %al, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cx
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 0FBEC8[ ]+movsb %al, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> @@ -82,7 +82,7 @@
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %cx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movsw %al, %ecx
> -[ ]*[1-9][0-9]*[ ]+movsw %ax, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 0FBFC8[ ]+movsw %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movswl %al, %cl
> --- a/gas/testsuite/gas/i386/movx64.l
> +++ b/gas/testsuite/gas/i386/movx64.l
> @@ -106,17 +106,17 @@
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cl
> [ ]*[1-9][0-9]*[ ]+movsb %rax, %cl
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %cx
> +[ ]*[1-9][0-9]* \?\?\?\? 660FBEC8[ ]+movsb %al, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %cx
> [ ]*[1-9][0-9]*[ ]+movsb %rax, %cx
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 0FBEC8[ ]+movsb %al, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsb %rax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> -[ ]*[1-9][0-9]*[ ]+movsb %al, %rcx
> +[ ]*[1-9][0-9]* \?\?\?\? 480FBEC8[ ]+movsb %al, %rcx
> [ ]*[1-9][0-9]*[ ]+movsb %ax, %rcx
> [ ]*[1-9][0-9]*[ ]+movsb %eax, %rcx
> [ ]*[1-9][0-9]*[ ]+movsb %rax, %rcx
> @@ -192,12 +192,12 @@
> [ ]*[1-9][0-9]*[ ]+movsw %rax, %cx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movsw %al, %ecx
> -[ ]*[1-9][0-9]*[ ]+movsw %ax, %ecx
> +[ ]*[1-9][0-9]* \?\?\?\? 0FBFC8[ ]+movsw %ax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %ecx
> [ ]*[1-9][0-9]*[ ]+movsw %rax, %ecx
> [ ]*[1-9][0-9]*[ ]*
> [ ]*[1-9][0-9]*[ ]+movsw %al, %rcx
> -[ ]*[1-9][0-9]*[ ]+movsw %ax, %rcx
> +[ ]*[1-9][0-9]* \?\?\?\? 480FBFC8[ ]+movsw %ax, %rcx
> [ ]*[1-9][0-9]*[ ]+movsw %eax, %rcx
> [ ]*[1-9][0-9]*[ ]+movsw %rax, %rcx
> [ ]*[1-9][0-9]*[ ]*
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -135,47 +135,37 @@
> mov, 0xa0, None, CpuNo64, D|W|No_sSuf|No_qSuf|No_ldSuf, { Disp16|Disp32|Unspecified|Byte|Word|Dword, Acc|Byte|Word|Dword }
> mov, 0xa0, None, Cpu64, D|W|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword }
> movabs, 0xa0, None, Cpu64, D|W|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword }
> -movq, 0xa1, None, Cpu64, D|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Disp64|Unspecified|Qword, Acc|Qword }
> mov, 0x88, None, 0, D|W|CheckRegSize|Modrm|No_sSuf|No_ldSuf|HLEPrefixRelease, { Reg8|Reg16|Reg32|Reg64, Reg8|Reg16|Reg32|Reg64|Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> -movq, 0x89, None, Cpu64, D|Modrm|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|HLEPrefixRelease, { Reg64, Reg64|Unspecified|Qword|BaseIndex }
> // In the 64bit mode the short form mov immediate is redefined to have
> // 64bit value.
> mov, 0xb0, None, 0, W|No_sSuf|No_qSuf|No_ldSuf, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32 }
> mov, 0xc6, 0, 0, W|Modrm|No_sSuf|No_ldSuf|HLEPrefixRelease|Optimize, { Imm8|Imm16|Imm32|Imm32S, Reg8|Reg16|Reg32|Reg64|Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> -movq, 0xc7, 0, Cpu64, Modrm|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|HLEPrefixRelease|Optimize, { Imm32S, Reg64|Qword|Unspecified|BaseIndex }
> mov, 0xb8, None, Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|Optimize, { Imm64, Reg64 }
> movabs, 0xb8, None, Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Imm64, Reg64 }
> -movq, 0xb8, None, Cpu64, Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Optimize, { Imm64, Reg64 }
> // The segment register moves accept WordReg so that a segment register
> // can be copied to a 32 bit register, and vice versa, without using a
> // size prefix. When moving to a 32 bit register, the upper 16 bits
> // are set to an implementation defined value (on the Pentium Pro, the
> // implementation defined value is zero).
> -mov, 0x8c, None, 0, RegMem|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { SReg, Reg16|Reg32|Reg64 }
> +mov, 0x8c, None, 0, RegMem|No_bSuf|No_sSuf|No_ldSuf|NoRex64, { SReg, Reg16|Reg32|Reg64 }
> mov, 0x8c, None, 0, D|Modrm|IgnoreSize|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { SReg, Word|Unspecified|BaseIndex }
> -movq, 0x8c, None, Cpu64, D|RegMem|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { SReg, Reg64 }
> -mov, 0x8e, None, 0, Modrm|IgnoreSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Reg16|Reg32|Reg64, SReg }
> +mov, 0x8e, None, 0, Modrm|IgnoreSize|No_bSuf|No_sSuf|No_ldSuf|NoRex64, { Reg16|Reg32|Reg64, SReg }
> // Move to/from control debug registers. In the 16 or 32bit modes
> // they are 32bit. In the 64bit mode they are 64bit.
> mov, 0xf20, None, Cpu386|CpuNo64, D|RegMem|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Control, Reg32 }
> mov, 0xf20, None, Cpu64, D|RegMem|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Control, Reg64 }
> -movq, 0xf20, None, Cpu64, D|RegMem|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Control, Reg64 }
> mov, 0xf21, None, Cpu386|CpuNo64, D|RegMem|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Debug, Reg32 }
> mov, 0xf21, None, Cpu64, D|RegMem|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Debug, Reg64 }
> -movq, 0xf21, None, Cpu64, D|RegMem|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Debug, Reg64 }
> mov, 0xf24, None, Cpu386|CpuNo64, D|RegMem|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Test, Reg32 }
>
> // Move after swapping the bytes
> movbe, 0x0f38f0, None, CpuMovbe, D|Modrm|No_bSuf|No_sSuf|No_ldSuf, { Word|Dword|Qword|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
>
> // Move with sign extend.
> -// "movsbl" & "movsbw" must not be unified into "movsb" to avoid
> -// conflict with the "movs" string move instruction.
> -movsbl, 0xfbe, None, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Byte|Unspecified|BaseIndex, Reg32 }
> -movsbw, 0xfbe, None, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Byte|Unspecified|BaseIndex, Reg16 }
> -movswl, 0xfbf, None, Cpu386, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Word|Unspecified|BaseIndex, Reg32 }
> -movsbq, 0xfbe, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Size64, { Reg8|Byte|Unspecified|BaseIndex, Reg64 }
> -movswq, 0xfbf, None, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Size64, { Reg16|Word|Unspecified|BaseIndex, Reg64 }
> +movsb, 0xfbe, None, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
> +movsw, 0xfbf, None, Cpu386, Modrm|No_bSuf|No_wSuf|No_sSuf|No_ldSuf, { 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 }
> 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 }
> @@ -492,9 +482,6 @@ set<cc>, 0xf9<cc:opc>, 0, Cpu386, Modrm|
> // String manipulation.
> cmps, 0xa6, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, {}
> cmps, 0xa6, None, 0, W|No_sSuf|No_ldSuf|IsStringEsOp0|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex, Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> -// Intel mode string compare.
> -cmpsd, 0xa7, None, Cpu386, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, {}
> -cmpsd, 0xa7, None, Cpu386, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsStringEsOp0|RepPrefixOk, { Dword|Unspecified|BaseIndex, Dword|Unspecified|BaseIndex }
> scmp, 0xa6, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, {}
> scmp, 0xa6, None, 0, W|No_sSuf|No_ldSuf|IsStringEsOp0|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex, Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> ins, 0x6c, None, Cpu186, W|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, {}
> @@ -509,9 +496,6 @@ slod, 0xac, None, 0, W|No_sSuf|No_ldSuf|
> slod, 0xac, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex, Acc|Byte|Word|Dword|Qword }
> movs, 0xa4, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, {}
> movs, 0xa4, None, 0, W|No_sSuf|No_ldSuf|IsStringEsOp1|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex, Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> -// Intel mode string move.
> -movsd, 0xa5, None, Cpu386, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsString|RepPrefixOk, {}
> -movsd, 0xa5, None, Cpu386, Size32|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IsStringEsOp1|RepPrefixOk, { Dword|Unspecified|BaseIndex, Dword|Unspecified|BaseIndex }
> smov, 0xa4, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, {}
> smov, 0xa4, None, 0, W|No_sSuf|No_ldSuf|IsStringEsOp1|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex, Byte|Word|Dword|Qword|Unspecified|BaseIndex }
> scas, 0xae, None, 0, W|No_sSuf|No_ldSuf|IsString|RepPrefixOk, {}
>
--
H.J.
next prev parent reply other threads:[~2022-08-17 20:29 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-16 7:27 [PATCH 0/7] x86: suffix handling changes Jan Beulich
2022-08-16 7:30 ` [PATCH 1/7] x86/Intel: restrict suffix derivation Jan Beulich
2022-08-17 19:19 ` H.J. Lu
2022-08-18 6:07 ` Jan Beulich
2022-08-18 14:46 ` H.J. Lu
2022-08-19 8:19 ` Jan Beulich
2022-08-19 14:23 ` H.J. Lu
2022-08-19 14:49 ` Jan Beulich
2022-08-19 17:00 ` H.J. Lu
2022-08-22 9:34 ` Jan Beulich
2022-08-22 14:38 ` H.J. Lu
2022-08-16 7:30 ` [PATCH 2/7] x86: insert "no error" enumerator in i386_error enumeration Jan Beulich
2022-08-17 19:19 ` H.J. Lu
2022-08-16 7:31 ` [PATCH 3/7] x86: move / quiesce pre-386 non-16-bit warning Jan Beulich
2022-08-17 19:21 ` H.J. Lu
2022-08-18 7:21 ` Jan Beulich
2022-08-18 15:30 ` H.J. Lu
2022-08-19 6:13 ` Jan Beulich
2022-08-19 14:18 ` H.J. Lu
2022-08-16 7:32 ` [PATCH 4/7] x86: improve match_template()'s diagnostics Jan Beulich
2022-08-17 20:24 ` H.J. Lu
2022-08-18 6:14 ` Jan Beulich
2022-08-18 14:51 ` H.J. Lu
2022-08-16 7:32 ` [PATCH 5/7] x86: re-work insn/suffix recognition Jan Beulich
2022-08-17 20:29 ` H.J. Lu [this message]
2022-08-18 6:24 ` Jan Beulich
2022-08-18 15:14 ` H.J. Lu
2022-08-19 8:28 ` Jan Beulich
2022-08-23 2:00 ` H.J. Lu
2022-08-26 9:26 ` Jan Beulich
2022-08-26 18:46 ` H.J. Lu
2022-09-06 6:40 ` Jan Beulich
2022-09-06 21:53 ` H.J. Lu
2022-09-07 7:17 ` Jan Beulich
2022-09-26 23:52 ` H.J. Lu
2022-09-28 12:49 ` Jan Beulich
2022-09-28 19:33 ` H.J. Lu
2022-09-29 8:08 ` Jan Beulich
2022-09-29 16:00 ` H.J. Lu
2022-09-29 16:06 ` Jan Beulich
2022-09-29 16:20 ` H.J. Lu
2022-08-16 7:33 ` [PATCH 6/7] x86-64: further re-work insn/suffix recognition to also cover MOVSL Jan Beulich
2022-08-16 7:34 ` [PATCH 7/7] ix86: don't recognize/derive Q suffix in the common case Jan Beulich
2022-08-17 20:36 ` H.J. Lu
2022-08-18 6:29 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAMe9rOqCJXZe2nO6vCKRhWm2SuC1x3T-3ZLEdDQc8FB5TuHTJw@mail.gmail.com \
--to=hjl.tools@gmail.com \
--cc=binutils@sourceware.org \
--cc=jbeulich@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).