On 27.02.2026 11:58, Edwin Török wrote:
> --- a/tools/tests/x86_emulator/test_x86_emulator.c
> +++ b/tools/tests/x86_emulator/test_x86_emulator.c
> @@ -1882,8 +1882,13 @@ int main(int argc, char **argv)
>  #define decl_insn(which) extern const unsigned char which[], \
>                           which##_end[] asm ( ".L" #which "_end" )
>  #define put_insn(which, insn) ".pushsection .test\n" \
> -                              #which ": " insn "\n"  \
> +                              ".ifndef "#which"\n" \
> +                              #which ": \n" \
> +                              ".endif\n" \
> +                              insn "\n"  \
> +                              ".ifndef .L"#which"_end\n" \
>                                ".L" #which "_end:\n"  \
> +                              ".endif\n" \
>                                ".popsection"

Nice idea, but why multiple .ifndef, and why emitting the insn even if the
labels are already there (and hence won't be emitted a 2nd time)?

Further, if the compiler unrolls a loop and instantiates such a put_insn()
twice, it could pick different inputs (where flexibility is allowed). Most
present uses (including ones I have pending) meet this requirement (i.e.
permit only a single register per operand), but vmovdqu{32,16}_to_mem,
evex_vcvtph2ps, vpcompress{d,q,w},  vpdpwssd_{vex1,vex2,evex}, and
vmovsh_to_mem don't. {,v}movsd{,_masked}_to_mem, pcmp{e,i}str{i,m} and a
few more could also end up being problematic if different addressing was
used for the memory operand(s).

None of those sit in loops, I think, so we may be safe. But the constraints
need properly writing down in a comment, I think.

> @@ -5248,7 +5253,7 @@ int main(int argc, char **argv)
>          memset(res + 3, ~0, 8);
>          regs.eax = (unsigned long)res;
>          regs.ecx = ~0;
> -        for ( i = 0; i < 2; ++i )
> +        for (i = 0; i < 2; ++i )
>          {
>              decl_insn(vmovsh_to_mem);

Excuse me?

Jan

Reply via email to