diff options
| author | iximeow <me@iximeow.net> | 2026-06-05 08:35:17 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-06-21 16:44:21 +0000 |
| commit | d8d1662bc0469901a25658679e07082aa4d71d22 (patch) | |
| tree | 6f7cd55156a56efc3f623f69b01061db2e3ecf05 | |
| parent | e38dbea8cb456758c50f3593287acdca3983889e (diff) | |
64-bit: vex-prefix register extension..
| -rw-r--r-- | CHANGELOG | 3 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 11 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 22 |
3 files changed, 20 insertions, 16 deletions
@@ -23,6 +23,9 @@ `pmovsxwq`, and `cvtss2sd`. additionally, `lfs`, `lgs`, and `lss` in 64-bit mode have 32-bit operand forms (yielding 32 + 16 == 48 bits of memory accessed). +* fix many vex instructions having their modrm/mmm registers extended by an + incorrect VEX prefix bit. most errors were REX.X being used to extend the mmm-field + register, but hardware uses REX.B for this purpose. ## 2.1.0 diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 548aec3..9f04198 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -8745,7 +8745,7 @@ fn read_operands< } else { RegisterBank::D }; - instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().x(), opwidth); + instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().b(), opwidth); instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } @@ -8756,7 +8756,7 @@ fn read_operands< } else { RegisterBank::D }; - instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().x(), opwidth); + instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().b(), opwidth); instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; @@ -8768,7 +8768,7 @@ fn read_operands< } else { RegisterBank::D }; - instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().x(), opwidth); + instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().b(), opwidth); instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } @@ -8779,7 +8779,7 @@ fn read_operands< } else { RegisterBank::D }; - instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().x(), opwidth); + instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().b(), opwidth); instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } @@ -8790,7 +8790,8 @@ fn read_operands< } else { RegisterBank::D }; - instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().x(), opwidth); + // incssp register is extended by rex.b???? + instruction.regs[1] = RegSpec::from_parts(m, instruction.prefixes.rex_unchecked().b(), opwidth); instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 04e2589..6ae12ad 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -334,7 +334,7 @@ fn read_vex_operands< } }; instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().b(), bank); instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; @@ -373,7 +373,7 @@ fn read_vex_operands< } } instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().b(), bank); instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; @@ -415,7 +415,7 @@ fn read_vex_operands< } } instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().b(), bank); instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; @@ -1405,7 +1405,7 @@ fn read_vex_operands< RegisterBank::D }; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), bank); instruction.regs[3].bank = bank; let mem_oper = read_E(words, instruction, modrm, bank, sink)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1425,7 +1425,7 @@ fn read_vex_operands< RegisterBank::D }; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), bank); instruction.regs[3].bank = bank; let mem_oper = read_E(words, instruction, modrm, bank, sink)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1445,7 +1445,7 @@ fn read_vex_operands< RegisterBank::D }; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; @@ -1479,7 +1479,7 @@ fn read_vex_operands< RegisterBank::D }; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = mem_oper; @@ -1587,7 +1587,7 @@ fn read_vex_operands< VEXOperandCode::G_V_E_ymm_ymm4 => { let modrm = read_modrm(words)?; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::Y); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), RegisterBank::Y); instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_ymm(words, instruction, modrm, sink)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1604,7 +1604,7 @@ fn read_vex_operands< VEXOperandCode::G_V_E_xmm_xmm4 => { let modrm = read_modrm(words)?; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::X); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), RegisterBank::X); instruction.regs[3].bank = RegisterBank::X; let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1621,7 +1621,7 @@ fn read_vex_operands< VEXOperandCode::G_V_ymm_E_xmm => { let modrm = read_modrm(words)?; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::Y); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), RegisterBank::Y); instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1636,7 +1636,7 @@ fn read_vex_operands< VEXOperandCode::G_V_xmm_Ev_imm8 => { let modrm = read_modrm(words)?; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::X); + RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().r(), RegisterBank::X); instruction.regs[3].bank = RegisterBank::X; // TODO: but the memory access is word-sized let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?; |
