This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH v8 1/2] x86: replace adhoc (partly wrong) ambiguous operand checking for MOVSX/MOVZX
On Fri, Feb 14, 2020 at 4:26 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> For these to get treatment consistent with other operand size checking
> the special logic shouldn't live in md_assemble(), but process_suffix().
> And there's more logic involved than simply zapping the suffix.
>
> Note however that MOVS[BW]* and MOVZ[BW]* still won't be fully
> consistent, due to the objection to fold MOVS* templates just like was
> done for MOVZ* in c07315e0c6 ("x86: allow suffix-less movzw and 64-bit
> movzb").
>
> Note further that it is against my own intentions to have MOVSX/MOVZX
> silently default to a byte source in AT&T mode. This should happen only
> when the desination register is a 16-bit one. In all other cases there
> is an ambiguity, and the user should be warned. But it was explicitly
> requested for this to be done in a way inconsistent with everything
> else.
>
> Note finally that the assembler change points out (and this patch fixes)
> a wrong Intel syntax test introduced by bc31405ebb2c ("x86-64: Properly
> encode and decode movsxd"): When source code specifies a 16-bit
> destination register, disassembly expectations shouldn't have been to
> find a 32-bit one.
>
> gas/
> 2020-02-XX Jan Beulich <jbeulich@suse.com>
>
> PR gas/25438
> * config/tc-i386.c (md_assemble): Move movsx/movzx special
> casing ...
> (process_suffix): ... here. Consider just the first operand
> initially.
> (check_long_reg): Drop opcode 0x63 special case again.
> * testsuite/gas/i386/i386.s, testsuite/gas/i386/iamcu-1.s,
> testsuite/gas/i386/ilp32/x86-64.s, testsuite/gas/i386/x86_64.s:
> Move ambiguous operand size tests ...
> * testsuite/gas/i386/noreg16.s, testsuite/gas/i386/noreg32.s,
> testsuite/gas/i386/noreg64.s: ... here.
> * testsuite/gas/i386/i386.d, testsuite/gas/i386/i386-intel.d
> testsuite/gas/i386/iamcu-1.d, testsuite/gas/i386/ilp32/x86-64.d,
> testsuite/gas/i386/k1om.d, testsuite/gas/i386/l1om.d,
> testsuite/gas/i386/movx16.l, testsuite/gas/i386/movx32.l,
> testsuite/gas/i386/movx64.l, testsuite/gas/i386/noreg16.d,
> testsuite/gas/i386/noreg32.d, testsuite/gas/i386/noreg64.d,
> testsuite/gas/i386/x86-64-movsxd.d,
> testsuite/gas/i386/x86-64-movsxd-intel.d,
> testsuite/gas/i386/x86_64.d, testsuite/gas/i386/x86_64-intel.d:
> Adjust expectations.
> * testsuite/gas/i386/movx16.s, testsuite/gas/i386/movx16.l,
> testsuite/gas/i386/movx32.s, testsuite/gas/i386/movx32.l,
> testsuite/gas/i386/movx64.s, testsuite/gas/i386/movx64.l: New.
> * testsuite/gas/i386/i386.exp: Run new tests.
>
> opcodes/
> 2020-02-XX Jan Beulich <jbeulich@suse.com>
>
> PR gas/25438
> * i386-opc.tbl (movsx): Fold patterns. Also allow Reg32 as
> destination for Cpu64-only variant.
> (movsxd): Also allow Reg32 as destination. Drop Rex64.
> (movzx): Fold patterns.
> * i386-tbl.h: Re-generate.
> ---
> v8: Silently default movsx/movsx to byte source in AT&T mode
> irrespective of destination register size.
> v7: Merge with previously separate patch introducing new testcases.
> v6: Move to end of series.
> v5: Re-base.
> v4: Re-base.
> v3: Re-base.
> v2: Undo No_lSuf addition to MOVSXD template. Drop bogus / pointless
> !i.tm.opcode_modifier.rex64 part of conditional in md_assemble().
> Re-base over changes earlier in the series.
>
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -132,13 +132,9 @@ movswl, 2, 0xfbf, None, 2, Cpu386, Modrm
> movsbq, 2, 0xfbe, None, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg8|Byte|Unspecified|BaseIndex, Reg64 }
> movswq, 2, 0xfbf, None, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg16|Word|Unspecified|BaseIndex, Reg64 }
> movslq, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg32|Dword|Unspecified|BaseIndex, Reg64 }
> -// Intel Syntax next 3 insns
> -movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
> -movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
> -movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|ATTSyntax, { Reg32|Unspecified|BaseIndex, Reg64 }
> -movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg8|Byte|BaseIndex, Reg16|Reg32|Reg64 }
> -movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
> -movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }
> +// Intel Syntax next 2 insns
^^^^^^^^^^^^^^^^ Is this comment correct?
> +movsx, 2, 0xfbe, None, 2, Cpu386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
> +movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
> movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
> movsxd, 2, 0x63, None, 1, Cpu64, Amd64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
> movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 }
> @@ -146,12 +142,9 @@ movsxd, 2, 0x63, None, 1, Cpu64, Intel64
> // Move with zero extend.
> movzb, 2, 0xfb6, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { Reg8|Byte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
> movzw, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_wSuf|No_sSuf|No_ldSuf, { Reg16|Word|Unspecified|BaseIndex, Reg32|Reg64 }
> -// Intel Syntax next 2 insns (the 64-bit variants are not particulary
> +// Intel Syntax next insn (the 64-bit variant is not particulary
^^^^^^^^^^^^^^^^ Is this comment correct?
> // useful since the zero extend 32->64 is implicit, but we can encode them).
> -movzx, 2, 0xfb6, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
> -movzx, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|ATTSyntax, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
> -movzx, 2, 0xfb6, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg8|Byte|BaseIndex, Reg16|Reg32|Reg64 }
> -movzx, 2, 0xfb7, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
> +movzx, 2, 0xfb6, None, 2, Cpu386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
>
> // Push instructions.
> push, 1, 0x50, None, 1, CpuNo64, No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32 }
>
--
H.J.