>>
>>      case X86_SIZE_ps: /* SSE/AVX packed single precision */
>> -    case X86_SIZE_pd: /* SSE/AVX packed double precision */
>> -        *ot = s->vex_l ? MO_256 : MO_128;
>> +    case X86_SIZE_pd: { /* SSE/AVX packed double precision */
>> +            bool is_scalar = (e->s0 == X86_SIZE_ss || e->s0 == X86_SIZE_sd 
>> ||
>> +                              e->s1 == X86_SIZE_ss || e->s1 == X86_SIZE_sd 
>> ||
>> +                              e->s2 == X86_SIZE_ss || e->s2 == X86_SIZE_sd);
>> +            *ot = (s->vex_l && !is_scalar) ? MO_256 : MO_128;
>> +        }
>
>
> Oh, this also applies to VMOVSS, VSQRTSS, etc. but that's actually correct - 
> they're all VEX.LIG. It's worth listing these instructions above the 
> declaration of is_scalar.
>
> Paolo

Checked which instructions are actually affected by this patch:
```
$ grep -Rn ',\s*s[sd]' | grep OP | grep -E ',\s*(x|ps|pd)'
tcg/decode-new.c.inc:999:    [0x0a] = X86_OP_ENTRY4(VROUNDSS,   V,x,
H,x, W,ss, vex3 cpuid(SSE41) p_66),
tcg/decode-new.c.inc:1000:    [0x0b] = X86_OP_ENTRY4(VROUNDSD,   V,x,
H,x, W,sd, vex3 cpuid(SSE41) p_66),
tcg/decode-new.c.inc:1056:        X86_OP_ENTRY3(VMOVSS_ld,  V,x,  H,x,
      M,ss, vex5),
tcg/decode-new.c.inc:1057:        X86_OP_ENTRY3(VMOVSD_ld,  V,x,  H,x,
      M,sd, vex5),
tcg/decode-new.c.inc:1079:        X86_OP_ENTRY3(VMOVSS_st,  M,ss,
None,None, V,x, vex5),
tcg/decode-new.c.inc:1080:        X86_OP_ENTRY3(VMOVLPx_st, M,sd,
None,None, V,x, vex5), /* MOVSD */
tcg/decode-new.c.inc:1163:        X86_OP_ENTRY3(VMOVSS_st,  M,ss,
None,None, V,x, vex4 cpuid(SSE4A)), /* MOVNTSS */
tcg/decode-new.c.inc:1164:        X86_OP_ENTRY3(VMOVLPx_st, M,sd,
None,None, V,x, vex4 cpuid(SSE4A)), /* MOVNTSD */
$
```
After running some tests, it looks like the behavior of (V)ROUNDSS,
(V)ROUNDSD, (V)MOVSS and (V)MOVSD is actually modified by this patch.
(MOVNTSS and MOVNTSD do not generate different TCG ops with and
without the patch applied. However, the VEX prefix
is actually illegal for these two AMD-specific instructions (tested on
AMD EPYC 7763; material for a different patch, I guess))

Also, VSQRTSS and VSQRTSD are actually raising an invalid opcode
exception when VEX.L is set
That's because:
1. `vex_special` field of VSQRTSS/VSQRTSD opcode entries is set to
`X86_VEX_REPScalar`
2. For entries with `vex_special == X86_VEX_REPScalar`,
`validate_vex()` raises the #UD
    if `(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) != 0` and `s->vex_l` is set
Intel Core i3-6100 and AMD EPYC 7763 do not raise #UD when this
happens. (looks like another patch material)

I will send a v2 with a comment listing (V)ROUNDSS, (V)ROUNDSD,
(V)MOVSS, (V)MOVSD as the instructions affected by this change

Reply via email to