diff options
| author | iximeow <me@iximeow.net> | 2026-04-17 02:22:24 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-05-25 00:59:27 +0000 |
| commit | 470ddb9a0329a8f1823674bca2c108e012ca2780 (patch) | |
| tree | c5ccc556fdde40ad263caff9dbdb6427597d0a5b /src | |
| parent | a049351c5d512710f557ffb45ee6391fc86a3dc6 (diff) | |
more precise about 0f0d prefetch/nop
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/mod.rs | 14 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 18 | ||||
| -rw-r--r-- | src/real_mode/mod.rs | 18 |
3 files changed, 21 insertions, 29 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 4288eb9..5e8dafa 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -7223,8 +7223,6 @@ fn read_operands< OperandCase::ModRM_0x0f0d => { let r = instruction.regs[0].num & 0b111; - let bank = bank_from_prefixes_64(SizeCode::vq, instruction.prefixes); - match r { 1 => { instruction.opcode = Opcode::PREFETCHW; @@ -7233,12 +7231,14 @@ fn read_operands< instruction.opcode = Opcode::NOP; } } - instruction.operands[0] = mem_oper; - if instruction.operands[0] != OperandSpec::RegMMM { - instruction.mem_size = 64; - } else { - instruction.regs[1].bank = bank; + if mem_oper == OperandSpec::RegMMM { + // *found* this from running `0f0dc0` under KVM on a Zen 5 system. this is + // consistent with the register number being used to pick kinds of prefetch. + return Err(DecodeError::InvalidOperand); } + + instruction.operands[0] = mem_oper; + instruction.mem_size = 64; instruction.operand_count = 1; } OperandCase::ModRM_0x0f0f => { diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 89c5dfd..eeb2942 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -7087,12 +7087,6 @@ fn read_operands< OperandCase::ModRM_0x0f0d => { let r = instruction.regs[0].num & 0b111; - let bank = if instruction.prefixes.operand_size() { - RegisterBank::W - } else { - RegisterBank::D - }; - match r { 1 => { instruction.opcode = Opcode::PREFETCHW; @@ -7101,12 +7095,14 @@ fn read_operands< instruction.opcode = Opcode::NOP; } } - instruction.operands[0] = mem_oper; - if instruction.operands[0] != OperandSpec::RegMMM { - instruction.mem_size = 64; - } else { - instruction.regs[1].bank = bank; + if mem_oper == OperandSpec::RegMMM { + // *found* this from running `0f0dc0` under KVM on a Zen 5 system. this is + // consistent with the register number being used to pick kinds of prefetch. + return Err(DecodeError::InvalidOperand); } + + instruction.operands[0] = mem_oper; + instruction.mem_size = 64; instruction.operand_count = 1; } OperandCase::ModRM_0x0f0f => { diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 559cac3..cab3fb1 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -7126,12 +7126,6 @@ fn read_operands< OperandCase::ModRM_0x0f0d => { let r = instruction.regs[0].num & 0b111; - let bank = if !instruction.prefixes.operand_size() { - RegisterBank::W - } else { - RegisterBank::D - }; - match r { 1 => { instruction.opcode = Opcode::PREFETCHW; @@ -7140,12 +7134,14 @@ fn read_operands< instruction.opcode = Opcode::NOP; } } - instruction.operands[0] = mem_oper; - if instruction.operands[0] != OperandSpec::RegMMM { - instruction.mem_size = 64; - } else { - instruction.regs[1].bank = bank; + if mem_oper == OperandSpec::RegMMM { + // *found* this from running `0f0dc0` under KVM on a Zen 5 system. this is + // consistent with the register number being used to pick kinds of prefetch. + return Err(DecodeError::InvalidOperand); } + + instruction.operands[0] = mem_oper; + instruction.mem_size = 64; instruction.operand_count = 1; } OperandCase::ModRM_0x0f0f => { |
