[PATCH] x86-64: Properly encode and decode movsxd

Jan Beulich jbeulich@suse.com
Fri Jan 24 08:21:00 GMT 2020


On 23.01.2020 21:24, H.J. Lu wrote:
> movsxd is a 64-bit only instruction.  It supports both 16-bit and 32-bit
> destination registers.  Its AT&T mnemonic is movslq which only supports
> 64-bit destination register.  There is also a discrepancy between AMD64
> and Intel64 on movsxd with 16-bit destination register.  AMD64 supports
> 32-bit source operand and Intel64 supports 16-bit source operand.
> 
> This patch updates movsxd encoding and decoding to alow 16-bit and 32-bit
> destination registers.  It also handles movsxd with 16-bit destination
> register for AMD64 and Intel 64.

I appreciate you taking care of the disassembler and documentation
side, but would you mind pointing out what's wrong with the previously
posted patches making the assembler deal with this correctly? For
example, I get away ...

> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -6690,7 +6690,9 @@ check_long_reg (void)
>  	     && i.tm.operand_types[op].bitfield.dword)
>        {
>  	if (intel_syntax
> -	    && i.tm.opcode_modifier.toqword
> +	    && (i.tm.opcode_modifier.toqword
> +		/* Also convert to QWORD for MOVSXD.  */
> +		|| i.tm.base_opcode == 0x63)
>  	    && i.types[0].bitfield.class != RegSIMD)

... without such a (pretty arbitrary) adjustment (as an aside: the
comment is slightly misleading in that the change also affects some
MOVSX templates), while ...

> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -135,7 +135,9 @@ movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|R
>  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 }
> -movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg32|Dword|Unspecified|BaseIndex, 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 }

... e.g. all of this matches what, in sum, the two patches I've
submitted (which also deal with other insns) do as well. In the
end this means that I'll want to undo the check_long_reg()
adjustment above, in which case my patches could as well go in
alongside your disassembler adjustment.

Jan



More information about the Binutils mailing list