[PATCH V2] Support {evex} pseudo prefix for decode evex promoted insns without egpr32.
Jan Beulich
jbeulich@suse.com
Mon Mar 25 12:31:18 GMT 2024
(sorry, previous mail went out unfinished by mistake)
On 22.03.2024 10:49, Cui, Lili wrote:
> From: "Hu, Lin1" <lin1.hu@intel.com>
>
> Based on the V1, there are mainly the following changes:
> 1. Added more test cases to cover each ins template.
> 2. The Intel format test has been removed in this patch.
> 3. Droped the newly added %XE and use evex_from_legacy for unified judgment.
> 4. Add %ME to movbe to print {evex} correctly.
Hmm. Iirc I had outlined how to deal with this without introducing a
single-use macro. I'm not outright opposed, but I'd like to understand
why you've chosen not to deal with this by having decode go through
mod_table[].
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/noreg64-evex.s
> @@ -0,0 +1,74 @@
> +# Check 64-bit insns not sizeable through register operands with evex
> +
> + .text
> +_start:
> + {evex} adc $1, (%rax)
> + {evex} adc $0x89, (%rax)
> + {evex} adc $0x1234, (%rax)
> + {evex} adc $0x12345678, (%rax)
> + {evex} add $1, (%rax)
> + {evex} add $0x89, (%rax)
> + {evex} add $0x1234, (%rax)
> + {evex} add $0x12345678, (%rax)
> + {evex} and $1, (%rax)
> + {evex} and $0x89, (%rax)
> + {evex} and $0x1234, (%rax)
> + {evex} and $0x12345678, (%rax)
> + {evex} crc32 (%rax), %eax
> + {evex} crc32 (%rax), %rax
> + {evex} dec (%rax)
> + {evex} div (%rax)
> + {evex} idiv (%rax)
> + {evex} imul (%rax)
> + {evex} inc (%rax)
> + {evex} mul (%rax)
> + {evex} neg (%rax)
> + {evex} not (%rax)
> + {evex} or $1, (%rax)
> + {evex} or $0x89, (%rax)
> + {evex} or $0x1234, (%rax)
> + {evex} or $0x12345678, (%rax)
> + {evex} rcl $1, (%rax)
> + {evex} rcl $2, (%rax)
> + {evex} rcl %cl, (%rax)
> + {evex} rcl (%rax)
> + {evex} rcr $1, (%rax)
> + {evex} rcr $2, (%rax)
> + {evex} rcr %cl, (%rax)
> + {evex} rcr (%rax)
> + {evex} rol $1, (%rax)
> + {evex} rol $2, (%rax)
> + {evex} rol %cl, (%rax)
> + {evex} rol (%rax)
> + {evex} ror $1, (%rax)
> + {evex} ror $2, (%rax)
> + {evex} ror %cl, (%rax)
> + {evex} ror (%rax)
> + {evex} sbb $1, (%rax)
> + {evex} sbb $0x89, (%rax)
> + {evex} sbb $0x1234, (%rax)
> + {evex} sbb $0x12345678, (%rax)
> + {evex} sal $1, (%rax)
> + {evex} sal $2, (%rax)
> + {evex} sal %cl, (%rax)
> + {evex} sal (%rax)
> + {evex} sar $1, (%rax)
> + {evex} sar $2, (%rax)
> + {evex} sar %cl, (%rax)
> + {evex} sar (%rax)
I realize it was my mistake originally, but may I ask that we don't further
spread it: sbb really wants to come after sal and sar.
> --- a/gas/testsuite/gas/i386/x86-64-apx-evex-promoted-bad.d
> +++ b/gas/testsuite/gas/i386/x86-64-apx-evex-promoted-bad.d
> @@ -30,16 +30,16 @@ Disassembly of section .text:
> [ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
> [ ]*[a-f0-9]+:[ ]+62 f2 fc 18 f5[ ]+\(bad\)
> [ ]*[a-f0-9]+:[ ]+0c 18[ ]+or.*
> -[ ]*[a-f0-9]+:[ ]+62 f4 e4[ ]+\(bad\)
> +[ ]*[a-f0-9]+:[ ]+62 f4 e4[ ]+\{evex\} \(bad\)
> [ ]*[a-f0-9]+:[ ]+08 ff[ ]+.*
> [ ]*[a-f0-9]+:[ ]+04 08[ ]+.*
> -[ ]*[a-f0-9]+:[ ]+62 f4 3c[ ]+\(bad\)
> +[ ]*[a-f0-9]+:[ ]+62 f4 3c[ ]+\{evex\} \(bad\)
Why is this? What's the criteria for {evex} to appear ahead of (bad)? And
if so for EVEX, shouldn't VEX gain {vex} in such cases, too? (Which is
really the opposite I mean to indicate: No such prefixes should ever appear
here. If anything we should present unrecognized VEX/EVEX encodings in a
sufficiently generic way, including all of their - similarly generalized -
operands.)
> [ ]*[a-f0-9]+:[ ]+08 8f c0 ff ff ff[ ]+or.*
> [ ]*[a-f0-9]+:[ ]+62 74 7c 18 8f c0[ ]+pop2 %rax,\(bad\)
> [ ]*[a-f0-9]+:[ ]+62 d4 24 18 8f[ ]+\(bad\)
> [ ]*[a-f0-9]+:[ ]+c3[ ]+.*
> [ ]*[a-f0-9]+:[ ]+62 e4 7e 08 dc 20[ ]+aesenc128kl \(%rax\),%xmm20\(bad\)
> -[ ]*[a-f0-9]+:[ ]+62 b4 7c 08 d9 c4[ ]+sha1msg1 %xmm20\(bad\),%xmm0
> +[ ]*[a-f0-9]+:[ ]+62 b4 7c 08 d9 c4[ ]+{evex} sha1msg1 %xmm20\(bad\),%xmm0
Why would {evex} need to appear here? There's no non-EVEX encoding using
%xmm20, is there? It shouldn't matter that %xmm20 really is wrong to use
here in the first place. It's (wrong) use cannot be expressed using REX2.
If having the pseudo-prefix appear here meaningfully simplifies the code,
then at the very least the expectations here should only permit, but not
demand its presence.
That said, I don't see how this test would have succeeded in your
testing: There are backslashes missing to escape the figure braces.
> @@ -10398,6 +10402,7 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
> int cond = 1;
> unsigned int l = 0, len = 0;
> char last[4];
> + bool b_done = false;
Mind me asking what "b" in this identifier is intended to stand for?
> @@ -10411,6 +10416,12 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
> switch (*p)
> {
> default:
> + if (ins->evex_type == evex_from_legacy && !ins->vex.nd
> + && !(ins->rex2 & 7) && !b_done)
> + {
> + oappend (ins, "{evex} ");
> + b_done = true;
> + }
> *ins->obufp++ = *p;
> break;
Right now it looks like it is okay to do this here; let's hope this
isn't going to bite us later.
> @@ -10547,6 +10558,11 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
> *ins->obufp++ = '}';
> *ins->obufp++ = ' ';
> break;
> + case 'M':
> + if (ins->modrm.mod != 3 && !(ins->rex2 & 7))
Hmm, according to the description of %ME you ought to also check for
no NDD, even if right now the only use site (MOVBE) doesn't allow for
that.
> @@ -10588,7 +10604,11 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
> oappend (ins, "{nf} ");
> /* This bit needs to be cleared after it is consumed. */
> ins->vex.nf = false;
> + b_done = true;
> }
> + else if (ins->evex_type == evex_from_vex && !(ins->rex2 & 7)
> + && ins->vex.v)
> + oappend (ins, "{evex} ");
Why would b_done not need setting here as well?
Jan
More information about the Binutils
mailing list