[PATCH 1/2] x86: CPU-qualify {disp16} / {disp32}
Cui, Lili
lili.cui@intel.com
Tue Nov 7 08:40:24 GMT 2023
> Subject: [PATCH 1/2] x86: CPU-qualify {disp16} / {disp32}
>
> {disp16} is invalid to use in 64-bit mode, while {disp32} is invalid to use on
> pre-386 CPUs. The latter, also affecting other (real) prefixes, further requires
> that like for insns we fully check the CPU flags; till now only Cpu64/CpuNo64
> were taken into consideration.
> ---
> While this is consistent with i386_index_check() diagnosing wrong {dispN} use
> as an error, that and the change here aren't consistent with documentation
> saying "prefer", suggesting such prefixes - like {rex}, albeit even there not fully
> consistent, seeing the error md_assemble() generates when used with
> VEX/XOP/EVEX encoded insns - are ignored when impossible to fulfill. Otoh
> the change here is consistent with {rex} being refused (rather than ignored)
> outside of 64-bit mode.
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -5781,7 +5781,8 @@ parse_insn (const char *line, char *mnem
> && current_templates
> && current_templates->start->opcode_modifier.isprefix)
> {
> - if (!cpu_flags_check_cpu64 (current_templates->start))
> + supported = cpu_flags_match (current_templates->start);
> + if (!(supported & CPU_FLAGS_64BIT_MATCH))
> {
> as_bad ((flag_code != CODE_64BIT
> ? _("`%s' is only supported in 64-bit mode") @@ -5789,6
> +5790,14 @@ parse_insn (const char *line, char *mnem
> insn_name (current_templates->start));
> return NULL;
> }
> + if (supported != CPU_FLAGS_PERFECT_MATCH)
> + {
> + as_bad (_("`%s' is not supported on `%s%s'"),
> + insn_name (current_templates->start),
> + cpu_arch_name ? cpu_arch_name : default_arch,
> + cpu_sub_arch_name ? cpu_sub_arch_name : "");
> + return NULL;
> + }
> /* If we are in 16-bit mode, do not allow addr16 or data16.
> Similarly, in 32-bit mode, do not allow addr32 or data32. */
> if ((current_templates->start->opcode_modifier.size == SIZE16
> --- a/gas/testsuite/gas/i386/prefix32.l
> +++ b/gas/testsuite/gas/i386/prefix32.l
> @@ -10,6 +10,13 @@
> .*:20: Error: data size .* `vaddps'
> .*:21: Error: data size .* `vaddpd'
> .*:25: Error: same type of prefix .*
> +.*:31: Error: `xacquire' is not supported on `i386'
> +.*:32: Error: `notrack' is not supported on `i386'
> +.*:33: Error: `bnd' is not supported on `i386'
> +.*:38: Error: `gs' is not supported on `i286'
> +.*:39: Error: `data32' is not supported on `i286'
> +.*:40: Error: `addr32' is not supported on `i286'
> +.*:41: Error: .*disp32.* is not supported on `i286'
> GAS LISTING .*
> #...
> [ ]*1[ ]+\.text
> @@ -40,4 +47,18 @@ GAS LISTING .*
> [ ]*26[ ]+\?\?\?\? 3E8B4500[ ]+ds mov
> %ss:\(%ebp\), %eax
> [ ]*27[ ]+\?\?\?\? 3E8B4500[ ]+ds mov
> %ds:\(%ebp\), %eax
> [ ]*28[ ]*
> +[ ]*[0-9]+[ ]+\.L386:
> +[ ]*[0-9]+[ ]+\.arch i386
> +[ ]*[0-9]+[ ]+xacquire lock add \[esi\], eax
> +[ ]*[0-9]+[ ]+notrack call eax
> +[ ]*[0-9]+[ ]+bnd call eax
> +[ ]*[0-9]+[ ]*
> +[ ]*[0-9]+[ ]+\.L286:
> +[ ]*[0-9]+[ ]+\.code16
> +[ ]*[0-9]+[ ]+\.arch i286
> +[ ]*[0-9]+[ ]+gs inc word ptr \[si\]
> +[ ]*[0-9]+[ ]+data32 nop
> +[ ]*[0-9]+[ ]+addr32 nop
> +[ ]*[0-9]+[ ]+\{disp32\} nop
> +[ ]*[0-9]+[ ]*
> #pass
> --- a/gas/testsuite/gas/i386/prefix32.s
> +++ b/gas/testsuite/gas/i386/prefix32.s
> @@ -26,4 +26,18 @@ prefix:
> ds mov %ss:(%ebp), %eax
> ds mov %ds:(%ebp), %eax
>
> +.L386:
> + .arch i386
> + xacquire lock add [esi], eax
> + notrack call eax
> + bnd call eax
> +
> +.L286:
> + .code16
> + .arch i286
> + gs inc word ptr [si]
> + data32 nop
> + addr32 nop
> + {disp32} nop
> +
> .p2align 4,0
> --- a/gas/testsuite/gas/i386/prefix64.l
> +++ b/gas/testsuite/gas/i386/prefix64.l
> @@ -3,12 +3,13 @@
> .*:7: Error: invalid .* `addss' after `repne'
> .*:8: Error: invalid .* `vaddss' after `repe'
> .*:9: Error: invalid .* `vaddss' after `repne'
> -.*:14: Error: same type of prefix .*
> -.*:15: Error: same type of prefix .*
> -.*:18: Error: data size .* `addps'
> -.*:19: Error: data size .* `addpd'
> -.*:20: Error: data size .* `vaddps'
> -.*:21: Error: data size .* `vaddpd'
> +.*:11: Error: .*disp16.* is not supported .*
> +.*:16: Error: same type of prefix .*
> +.*:17: Error: same type of prefix .*
> +.*:20: Error: data size .* `addps'
> +.*:21: Error: data size .* `addpd'
> +.*:22: Error: data size .* `vaddps'
> +.*:23: Error: data size .* `vaddpd'
> GAS LISTING .*
> #...
> [ ]*1[ ]+\.text
> @@ -21,16 +22,18 @@ GAS LISTING .*
> [ ]*8[ ]+repe vaddss %xmm0, %xmm0, %xmm0
> [ ]*9[ ]+repne vaddss %xmm0, %xmm0, %xmm0
> [ ]*10[ ]*
> -[ ]*11[ ]+\.Lrep_ret:
> -[ ]*12[ ]+\?\?\?\? F2C3[ ]+bnd ret
> -[ ]*13[ ]+\?\?\?\? F3C3[ ]+rep ret
> -[ ]*14[ ]+bnd rep ret
> -[ ]*15[ ]+rep bnd ret
> -[ ]*16[ ]*
> -[ ]*17[ ]+\.Ldata16:
> -[ ]*18[ ]+data16 addps %xmm0, %xmm0
> -[ ]*19[ ]+data16 addpd %xmm0, %xmm0
> -[ ]*20[ ]+data16 vaddps %xmm0, %xmm0, %xmm0
> -[ ]*21[ ]+data16 vaddpd %xmm0, %xmm0, %xmm0
> -[ ]*22[ ]*
> +[ ]*[0-9]+[ ]+\{disp16\} nop
> +[ ]*[0-9]+[ ]*
> +[ ]*[0-9]+[ ]+\.Lrep_ret:
> +[ ]*[0-9]+[ ]+\?\?\?\? F2C3[ ]+bnd ret
> +[ ]*[0-9]+[ ]+\?\?\?\? F3C3[ ]+rep ret
> +[ ]*[0-9]+[ ]+bnd rep ret
> +[ ]*[0-9]+[ ]+rep bnd ret
> +[ ]*[0-9]+[ ]*
> +[ ]*[0-9]+[ ]+\.Ldata16:
> +[ ]*[0-9]+[ ]+data16 addps %xmm0, %xmm0
> +[ ]*[0-9]+[ ]+data16 addpd %xmm0, %xmm0
> +[ ]*[0-9]+[ ]+data16 vaddps %xmm0, %xmm0, %xmm0
> +[ ]*[0-9]+[ ]+data16 vaddpd %xmm0, %xmm0, %xmm0
> +[ ]*[0-9]+[ ]*
> #pass
> --- a/gas/testsuite/gas/i386/prefix64.s
> +++ b/gas/testsuite/gas/i386/prefix64.s
> @@ -8,6 +8,8 @@ prefix:
> repe vaddss %xmm0, %xmm0, %xmm0
> repne vaddss %xmm0, %xmm0, %xmm0
>
> + {disp16} nop
> +
> .Lrep_ret:
> bnd ret
> rep ret
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -890,7 +890,7 @@ rex.wrxb, 0x4f, x64, NoSuf|IsPrefix, {}
>
> // Pseudo prefixes (base_opcode == PSEUDO_PREFIX)
>
> -<pseudopfx:ident:cpu, disp8:Disp8:0, disp16:Disp16:0, disp32:Disp32:0, +
> +<pseudopfx:ident:cpu, disp8:Disp8:0, disp16:Disp16:No64,
> +disp32:Disp32:i386, +
> load:Load:0, store:Store:0, +
> vex:VEX:0, vex2:VEX:0, vex3:VEX3:0, evex:EVEX:0, +
> rex:REX:x64, nooptimize:NoOptimize:0>
LGTM
Lili.
More information about the Binutils
mailing list