[PATCH] x86: Add Evw to emit w suffix for several instrctions for word ptr
H.J. Lu
hjl.tools@gmail.com
Thu Jun 1 02:14:41 GMT 2023
On Fri, May 26, 2023 at 1:28 AM Haochen Jiang <haochen.jiang@intel.com> wrote:
>
> Hi Jan,
>
> I am trying to fix the questionable manner with this patch. See if it reaches
> all our expectation.
>
> Thx,
> Haochen
>
> Currently, for instructions lldt/ltr/verr/verw/lkgs, we are missing
> w suffix for memory operands like sldt/str do. Also the Ew usage is
> not that precise under this scenario. Add Evw to fix this problem.
>
> gas/ChangeLog:
>
> * testsuite/gas/i386/i386.exp: Add LKGS suffix test.
> * testsuite/gas/i386/opcode-intel.d: Add ltr, verr, verw.
> * testsuite/gas/i386/opcode-suffix.d: Ditto.
> * testsuite/gas/i386/opcode.d: Ditto.
> * testsuite/gas/i386/opcode.s: Ditto.
> * testsuite/gas/i386/x86-64-lkgs-suffix.d: New test.
> * testsuite/gas/i386/x86-64-lkgs-suffix.s: Ditto.
>
> opcodes/ChangeLog:
>
> * i386-dis.c (Evw): New.
> (v_w_mode): Ditto.
> (lldt, ltr, verr, verw, lkgs): Change from Ew to Evw.
> (intel_operand_size): Handle v_w_mode.
> (print_register): Ditto.
The suffix is needed in AT&T syntax when there is an ambiguity.
In these cases, there is no ambiguity. I don't think we should add
the unnecessary 'w' suffix here.
> ---
> gas/testsuite/gas/i386/i386.exp | 1 +
> gas/testsuite/gas/i386/opcode-intel.d | 3 +++
> gas/testsuite/gas/i386/opcode-suffix.d | 5 ++++-
> gas/testsuite/gas/i386/opcode.d | 3 +++
> gas/testsuite/gas/i386/opcode.s | 4 ++++
> gas/testsuite/gas/i386/x86-64-lkgs-suffix.d | 15 +++++++++++++++
> gas/testsuite/gas/i386/x86-64-lkgs-suffix.s | 7 +++++++
> opcodes/i386-dis.c | 20 +++++++++++++++-----
> 8 files changed, 52 insertions(+), 6 deletions(-)
> create mode 100644 gas/testsuite/gas/i386/x86-64-lkgs-suffix.d
> create mode 100644 gas/testsuite/gas/i386/x86-64-lkgs-suffix.s
>
> diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
> index bce865c83d1..58f32401610 100644
> --- a/gas/testsuite/gas/i386/i386.exp
> +++ b/gas/testsuite/gas/i386/i386.exp
> @@ -1194,6 +1194,7 @@ if [gas_64_check] then {
> run_list_test "x86-64-amx-complex-inval"
> run_dump_test "x86-64-fred"
> run_dump_test "x86-64-lkgs"
> + run_dump_test "x86-64-lkgs-suffix"
> run_list_test "x86-64-lkgs-inval"
> run_dump_test "x86-64-clzero"
> run_dump_test "x86-64-mwaitx-bdver4"
> diff --git a/gas/testsuite/gas/i386/opcode-intel.d b/gas/testsuite/gas/i386/opcode-intel.d
> index 7f641db2892..3a366757a6a 100644
> --- a/gas/testsuite/gas/i386/opcode-intel.d
> +++ b/gas/testsuite/gas/i386/opcode-intel.d
> @@ -589,6 +589,9 @@ Disassembly of section .text:
> *[0-9a-f]+: 85 d8 [ ]*test[ ]+eax,ebx
> *[0-9a-f]+: 85 18 [ ]*test[ ]+(DWORD PTR )?\[eax\],ebx
> *[0-9a-f]+: f1[ ]+int1
> + *[0-9a-f]+: 0f 00 98 90 90 90 90[ ]+ltr[ ]+(WORD PTR )?\[eax-0x6f6f6f70\]
> + *[0-9a-f]+: 0f 00 a0 90 90 90 90[ ]+verr[ ]+(WORD PTR )?\[eax-0x6f6f6f70\]
> + *[0-9a-f]+: 0f 00 a8 90 90 90 90[ ]+verw[ ]+(WORD PTR )?\[eax-0x6f6f6f70\]
> [ ]*[a-f0-9]+: 0f 4a 90 90 90 90 90 cmovp edx,DWORD PTR \[eax-0x6f6f6f70\]
> [ ]*[a-f0-9]+: 0f 4b 90 90 90 90 90 cmovnp edx,DWORD PTR \[eax-0x6f6f6f70\]
> [ ]*[a-f0-9]+: 66 0f 4a 90 90 90 90 90 cmovp dx,WORD PTR \[eax-0x6f6f6f70\]
> diff --git a/gas/testsuite/gas/i386/opcode-suffix.d b/gas/testsuite/gas/i386/opcode-suffix.d
> index 152c3b865a0..fdca16a8a6b 100644
> --- a/gas/testsuite/gas/i386/opcode-suffix.d
> +++ b/gas/testsuite/gas/i386/opcode-suffix.d
> @@ -248,7 +248,7 @@ Disassembly of section .text:
> *[0-9a-f]+: fc[ ]+cld
> *[0-9a-f]+: fd[ ]+std
> *[0-9a-f]+: ff 90 90 90 90 90[ ]+calll[ ]+\*-0x6f6f6f70\(%eax\)
> - *[0-9a-f]+: 0f 00 90 90 90 90 90[ ]+lldt[ ]+-0x6f6f6f70\(%eax\)
> + *[0-9a-f]+: 0f 00 90 90 90 90 90[ ]+lldtw[ ]+-0x6f6f6f70\(%eax\)
> *[0-9a-f]+: 0f 01 90 90 90 90 90[ ]+lgdtl[ ]+-0x6f6f6f70\(%eax\)
> *[0-9a-f]+: 0f 02 90 90 90 90 90[ ]+larl[ ]+-0x6f6f6f70\(%eax\),%edx
> *[0-9a-f]+: 0f 03 90 90 90 90 90[ ]+lsll[ ]+-0x6f6f6f70\(%eax\),%edx
> @@ -589,6 +589,9 @@ Disassembly of section .text:
> *[0-9a-f]+: 85 d8 [ ]*testl[ ]+%ebx,%eax
> *[0-9a-f]+: 85 18 [ ]*testl[ ]+%ebx,\(%eax\)
> *[0-9a-f]+: f1[ ]+int1
> + *[0-9a-f]+: 0f 00 98 90 90 90 90[ ]+ltrw[ ]+-0x6f6f6f70\(%eax\)
> + *[0-9a-f]+: 0f 00 a0 90 90 90 90[ ]+verrw[ ]+-0x6f6f6f70\(%eax\)
> + *[0-9a-f]+: 0f 00 a8 90 90 90 90[ ]+verww[ ]+-0x6f6f6f70\(%eax\)
> [ ]*[a-f0-9]+: 0f 4a 90 90 90 90 90 cmovpl -0x6f6f6f70\(%eax\),%edx
> [ ]*[a-f0-9]+: 0f 4b 90 90 90 90 90 cmovnpl -0x6f6f6f70\(%eax\),%edx
> [ ]*[a-f0-9]+: 66 0f 4a 90 90 90 90 90 cmovpw -0x6f6f6f70\(%eax\),%dx
> diff --git a/gas/testsuite/gas/i386/opcode.d b/gas/testsuite/gas/i386/opcode.d
> index c6ffb018a19..e792962f3c1 100644
> --- a/gas/testsuite/gas/i386/opcode.d
> +++ b/gas/testsuite/gas/i386/opcode.d
> @@ -588,6 +588,9 @@ Disassembly of section .text:
> 9f7: 85 d8 [ ]*test %ebx,%eax
> 9f9: 85 18 [ ]*test %ebx,\(%eax\)
> 9fb: f1 [ ]*int1
> + +[a-f0-9]+: 0f 00 98 90 90 90 90 ltr -0x6f6f6f70\(%eax\)
> + +[a-f0-9]+: 0f 00 a0 90 90 90 90 verr -0x6f6f6f70\(%eax\)
> + +[a-f0-9]+: 0f 00 a8 90 90 90 90 verw -0x6f6f6f70\(%eax\)
> [ ]*[a-f0-9]+: 0f 4a 90 90 90 90 90 cmovp -0x6f6f6f70\(%eax\),%edx
> [ ]*[a-f0-9]+: 0f 4b 90 90 90 90 90 cmovnp -0x6f6f6f70\(%eax\),%edx
> [ ]*[a-f0-9]+: 66 0f 4a 90 90 90 90 90 cmovp -0x6f6f6f70\(%eax\),%dx
> diff --git a/gas/testsuite/gas/i386/opcode.s b/gas/testsuite/gas/i386/opcode.s
> index 000fff3e852..800dc465f70 100644
> --- a/gas/testsuite/gas/i386/opcode.s
> +++ b/gas/testsuite/gas/i386/opcode.s
> @@ -587,6 +587,10 @@ foo:
>
> int1
>
> + ltr 0x90909090(%eax)
> + verr 0x90909090(%eax)
> + verw 0x90909090(%eax)
> +
> cmovpe 0x90909090(%eax),%edx
> cmovpo 0x90909090(%eax),%edx
> cmovpe 0x90909090(%eax),%dx
> diff --git a/gas/testsuite/gas/i386/x86-64-lkgs-suffix.d b/gas/testsuite/gas/i386/x86-64-lkgs-suffix.d
> new file mode 100644
> index 00000000000..5433938f54d
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-lkgs-suffix.d
> @@ -0,0 +1,15 @@
> +#as: -J --divide
> +#objdump: -dwMsuffix
> +#name: x86_64 LKGS insns (w/ suffix)
> +#source: x86-64-lkgs.d
> +
> +.*: +file format .*
> +
> +Disassembly of section \.text:
> +
> +0+ <_start>:
> +\s*[a-f0-9]+:\s*f2 42 0f 00 b4 f5 00 00 00 10\s+lkgsw 0x10000000\(%rbp,%r14,8\)
> +\s*[a-f0-9]+:\s*f2 41 0f 00 31\s+lkgsw \(%r9\)
> +\s*[a-f0-9]+:\s*f2 0f 00 b1 fe 00 00 00\s+lkgsw 0xfe\(%rcx\)
> +\s*[a-f0-9]+:\s*f2 0f 00 b2 00 ff ff ff\s+lkgsw -0x100\(%rdx\)
> +#pass
> diff --git a/gas/testsuite/gas/i386/x86-64-lkgs-suffix.s b/gas/testsuite/gas/i386/x86-64-lkgs-suffix.s
> new file mode 100644
> index 00000000000..a8a77e34d0c
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-lkgs-suffix.s
> @@ -0,0 +1,7 @@
> + .allow_index_reg
> + .text
> +_start:
> + lkgs 0x10000000(%rbp, %r14, 8)
> + lkgs (%r9)
> + lkgs 254(%rcx)
> + lkgs -256(%rdx)
> diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
> index 07fcf3269f9..1dfa7e2b71c 100644
> --- a/opcodes/i386-dis.c
> +++ b/opcodes/i386-dis.c
> @@ -387,6 +387,7 @@ fetch_error (const instr_info *ins)
> #define Eva { OP_E, va_mode }
> #define Ev_bnd { OP_E, v_bnd_mode }
> #define EvS { OP_E, v_swap_mode }
> +#define Evw { OP_E, v_w_mode }
> #define Ed { OP_E, d_mode }
> #define Edq { OP_E, dq_mode }
> #define Edb { OP_E, db_mode }
> @@ -605,6 +606,8 @@ enum
> v_swap_mode,
> /* operand size depends on address prefix */
> va_mode,
> + /* operand size depends on prefixes but ignore DFLAG */
> + v_w_mode,
> /* word operand */
> w_mode,
> /* double word operand */
> @@ -2747,10 +2750,10 @@ static const struct dis386 reg_table[][8] = {
> {
> { "sldtD", { Sv }, 0 },
> { "strD", { Sv }, 0 },
> - { "lldt", { Ew }, 0 },
> - { "ltr", { Ew }, 0 },
> - { "verr", { Ew }, 0 },
> - { "verw", { Ew }, 0 },
> + { "lldtD", { Evw }, 0 },
> + { "ltrD", { Evw }, 0 },
> + { "verrD", { Evw }, 0 },
> + { "verwD", { Evw }, 0 },
> { X86_64_TABLE (X86_64_0F00_REG_6) },
> { Bad_Opcode },
> },
> @@ -2997,7 +3000,7 @@ static const struct dis386 prefix_table[][4] = {
> { Bad_Opcode },
> { Bad_Opcode },
> { Bad_Opcode },
> - { "lkgs", { Ew }, 0 },
> + { "lkgsD", { Evw }, 0 },
> },
>
> /* PREFIX_0F01_REG_0_MOD_3_RM_6 */
> @@ -11420,12 +11423,18 @@ intel_operand_size (instr_info *ins, int bytemode, int sizeflag)
> /* Fall through. */
> case v_mode:
> case v_swap_mode:
> + case v_w_mode:
> case dq_mode:
> USED_REX (REX_W);
> if (ins->rex & REX_W)
> oappend (ins, "QWORD PTR ");
> else if (bytemode == dq_mode)
> oappend (ins, "DWORD PTR ");
> + else if (bytemode == v_w_mode)
> + {
> + oappend (ins, "WORD PTR ");
> + ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
> + }
> else
> {
> if (sizeflag & DFLAG)
> @@ -11648,6 +11657,7 @@ print_register (instr_info *ins, unsigned int reg, unsigned int rexmask,
> names = att_names8;
> break;
> case w_mode:
> + case v_w_mode:
> names = att_names16;
> break;
> case d_mode:
> --
> 2.31.1
>
--
H.J.
More information about the Binutils
mailing list