diff options
| author | iximeow <me@iximeow.net> | 2026-06-05 08:32:09 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-06-21 16:44:21 +0000 |
| commit | e38dbea8cb456758c50f3593287acdca3983889e (patch) | |
| tree | e6abc5573a21ee8f6eb6754d83aab846b0f72e32 /src/real_mode | |
| parent | a38cba0c4a4ed9a1ed763618e5efe3f4487b1ad0 (diff) | |
fix several instructions' incorrect memory or op2 size
Diffstat (limited to 'src/real_mode')
| -rw-r--r-- | src/real_mode/mod.rs | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 716148c..334c07a 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -6686,7 +6686,7 @@ fn read_operands< if instruction.operands[1] != OperandSpec::RegMMM { if [Opcode::PMOVSXBQ, Opcode::PMOVZXBQ].contains(&instruction.opcode) { instruction.mem_size = 2; - } else if [Opcode::PMOVZXBD, Opcode::UCOMISS, Opcode::COMISS, Opcode::CVTSS2SD].contains(&instruction.opcode) { + } else if [Opcode::PMOVZXBD, Opcode::PMOVSXBD, Opcode::PMOVZXWQ, Opcode::PMOVSXWQ, Opcode::UCOMISS, Opcode::COMISS, Opcode::CVTSS2SD].contains(&instruction.opcode) { instruction.mem_size = 4; } else { instruction.mem_size = 8; @@ -7435,6 +7435,7 @@ fn read_operands< } 7 => { instruction.opcode = Opcode::RDPID; + // > "The value of CS.D and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction." instruction.operands[0] = read_E(words, instruction, modrm, RegisterBank::D, sink)?; if instruction.operands[0] != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); @@ -8336,12 +8337,16 @@ fn read_operands< instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 4 { - // TODO: this permits storing only to word-size registers - // spec suggets this might do something different for f.ex rdi? + // TODO: note that this was incorrectly choosing 16-bit operands every time instruction.opcode = Opcode::SMSW; instruction.operand_count = 1; instruction.mem_size = 2; - instruction.operands[0] = read_E(words, instruction, modrm, RegisterBank::W, sink)?; + let bank = if !instruction.prefixes.operand_size() { + RegisterBank::W + } else { + RegisterBank::D + }; + instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } else if r == 5 { let mod_bits = modrm >> 6; if mod_bits != 0b11 { |
