diff options
| -rw-r--r-- | CHANGELOG | 2 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 2 | ||||
| -rw-r--r-- | src/protected_mode/vex.rs | 2 | ||||
| -rw-r--r-- | src/real_mode/vex.rs | 2 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 2 | ||||
| -rw-r--r-- | test/protected_mode/mod.rs | 2 |
6 files changed, 7 insertions, 5 deletions
@@ -17,6 +17,8 @@ * fix vpbroadcast* with a memory source reporting incorrect memory sizes. the memory address being broadcast indicates the size, which is one byte/word/dword/qword. it is unrelated to the broadcasted-to vector length. +* fix incorrect index-vector-register size choice for vgatherdpd. the index register is xmm, not + depends-on-L xmm/ymm. testing instruction round-tripping through `masm` found a few bugs, which are also fixed in this release: diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index b787598..3380cf2 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -1408,7 +1408,7 @@ fn read_vex_operands< instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; - if instruction.opcode == Opcode::VPGATHERDQ { + if instruction.opcode == Opcode::VPGATHERDQ || instruction.opcode == Opcode::VGATHERDPD { instruction.regs[2].bank = RegisterBank::X; } else { instruction.regs[2].bank = index_bank; diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 429ad23..35ed395 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -1321,7 +1321,7 @@ fn read_vex_operands< instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; - if instruction.opcode == Opcode::VPGATHERDQ { + if instruction.opcode == Opcode::VPGATHERDQ || instruction.opcode == Opcode::VGATHERDPD { instruction.regs[2].bank = RegisterBank::X; } else { instruction.regs[2].bank = index_bank; diff --git a/src/real_mode/vex.rs b/src/real_mode/vex.rs index 3a7fbe3..6a74fe8 100644 --- a/src/real_mode/vex.rs +++ b/src/real_mode/vex.rs @@ -1321,7 +1321,7 @@ fn read_vex_operands< instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; - if instruction.opcode == Opcode::VPGATHERDQ { + if instruction.opcode == Opcode::VPGATHERDQ || instruction.opcode == Opcode::VGATHERDPD { instruction.regs[2].bank = RegisterBank::X; } else { instruction.regs[2].bank = index_bank; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 478a1fc..cd8fbbb 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -2924,7 +2924,7 @@ mod vex { testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b0_1111_001, 0x92, 0b00_000_100, 0xa1], "vgatherdps xmm8, dword [r9 + xmm12 * 4], xmm0"), testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b0_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdps ymm8, dword [r9 + ymm12 * 4], ymm0"), testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b1_1111_001, 0x92, 0b00_000_100, 0xa1], "vgatherdpd xmm8, qword [r9 + xmm12 * 4], xmm0"), - testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b1_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdpd ymm8, qword [r9 + ymm12 * 4], ymm0"), + testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b1_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdpd ymm8, qword [r9 + xmm12 * 4], ymm0"), testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b0_1111_001, 0x93, 0b00_000_100, 0xa1], "vgatherqps xmm8, dword [r9 + xmm12 * 4], xmm0"), testcase!(features { AVX2: true } &[0xc4, 0b000_00010, 0b0_1111_101, 0x93, 0b00_000_100, 0xa1], "vgatherqps xmm8, dword [r9 + ymm12 * 4], xmm0"), diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index b0e6772..0d3dd07 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -2807,7 +2807,7 @@ mod vex { testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b0_1111_001, 0x92, 0b00_000_100, 0xa1], "vgatherdps xmm0, dword [ecx + xmm12 * 4], xmm0"), testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b0_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdps ymm0, qword [ecx + ymm12 * 4], ymm0"), testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b1_1111_001, 0x92, 0b00_000_100, 0xa1], "vgatherdpd xmm0, dword [ecx + xmm12 * 4], xmm0"), - testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b1_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdpd ymm0, qword [ecx + ymm12 * 4], ymm0"), + testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b1_1111_101, 0x92, 0b00_000_100, 0xa1], "vgatherdpd ymm0, qword [ecx + xmm12 * 4], ymm0"), testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b0_1111_001, 0x93, 0b00_000_100, 0xa1], "vgatherqps xmm0, dword [ecx + xmm12 * 4], xmm0"), testcase!(features { AVX2: true } &[0xc4, 0b110_00010, 0b0_1111_101, 0x93, 0b00_000_100, 0xa1], "vgatherqps ymm0, qword [ecx + ymm12 * 4], ymm0"), |
