x86emu/emulator/
instruction.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Functions to help parse instructions.
5
6use crate::Cpu;
7use iced_x86::CodeSize;
8use iced_x86::Instruction;
9use iced_x86::Register;
10
11// TODO: replace with just .address_size() if https://github.com/icedland/iced/issues/389 is accepted
12pub fn address_size(instr: &Instruction) -> usize {
13    if instr.memory_base() != Register::None {
14        instr.memory_base().size()
15    } else if instr.memory_index() != Register::None {
16        instr.memory_index().size()
17    } else if instr.memory_displ_size() >= 2 {
18        instr.memory_displ_size() as usize
19    } else {
20        match instr.code_size() {
21            CodeSize::Code64 => 8,
22            CodeSize::Code32 => 4,
23            CodeSize::Code16 => 2,
24            CodeSize::Unknown => 8,
25        }
26    }
27}
28
29pub fn memory_op_offset<T: Cpu>(cpu: &mut T, instr: &Instruction, operand: u32) -> u64 {
30    instr
31        .virtual_address(operand, 0, |reg, _element_index, _element_size| {
32            if reg.is_gpr() {
33                Some(cpu.gp(reg.into()))
34            } else if reg.is_segment_register() {
35                // The segment base is ignored since it's applied in compute_and_validate_gva.
36                Some(0)
37            } else {
38                todo!("missing register support {:?}", reg)
39            }
40        })
41        .unwrap()
42}