AVX instruction VMOVDQU implementation error for YMM registers
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Expired
|
Undecided
|
Unassigned |
Bug Description
Hi,
Tested with Qemu 4.2.0, and with git version bddff6f6787c916
The x86 AVX instruction VMOVDQU doesn't work properly with YMM registers (32 bytes).
It works with XMM registers (16 bytes) though.
See the attached test case `ymm.c`: when copying from memory-to-ymm0 and then back from ymm0-to-memory using VMOVDQU, Qemu only copies the first 16 of the total 32 bytes.
```
user@ubuntu ~/Qemu % gcc -o ymm ymm.c -Wall -Wextra -Werror
user@ubuntu ~/Qemu % ./ymm
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
user@ubuntu ~/Qemu % ./x86_64-
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```
This seems to be because in `translate.c > gen_sse()`, the case handling the VMOVDQU instruction calls `gen_ldo_env_A0` which always performs a 16 bytes copy using two 8 bytes load and store operations (with `tcg_gen_
Instead, the `gen_ldo_env_A0` function should generate a copy with a size corresponding to the used register.
```
static void gen_sse(CPUX86State *env, DisasContext *s, int b,
{
[...]
case 0x26f: /* movdqu xmm, ea */
if (mod != 3) {
} else {
[...]
```
```
static inline void gen_ldo_
{
int mem_index = s->mem_index;
tcg_
tcg_
tcg_
tcg_
tcg_
}
```
tags: | added: tcg testcase |
Note: Qemu has been built with the following commands: list=x86_ 64-linux- user && make list=x86_ 64-linux- user --enable-avx2 && make
```
% ./configure --target-
OR
% ./configure --target-
```