hypervisor: emulator: Emulate MOVZX

MOV R/RM is a special case of MOVZX, so we generalize the mov_r_rm macro
to make it support both instructions.

Fixes: #2227

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2021-02-03 00:02:50 +01:00
parent 89008a49cf
commit 5ada3f59c8
2 changed files with 51 additions and 6 deletions

View File

@ -74,21 +74,27 @@ macro_rules! mov_rm_imm {
};
}
macro_rules! mov_r_rm {
($bound:ty) => {
macro_rules! movzx {
($src_op_size:ty, $dest_op_size:ty) => {
fn emulate(
&self,
insn: &Instruction,
state: &mut T,
platform: &mut dyn PlatformEmulator<CpuState = T>,
) -> Result<(), EmulationError<Exception>> {
let src_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform)
.map_err(EmulationError::PlatformEmulationError)?;
let src_value = get_op(
&insn,
1,
std::mem::size_of::<$src_op_size>(),
state,
platform,
)
.map_err(EmulationError::PlatformEmulationError)?;
set_op(
&insn,
0,
std::mem::size_of::<$bound>(),
std::mem::size_of::<$dest_op_size>(),
state,
platform,
src_value,
@ -102,6 +108,13 @@ macro_rules! mov_r_rm {
};
}
// MOV r/rm is a special case of MOVZX, where both operands have the same size.
macro_rules! mov_r_rm {
($op_size:ty) => {
movzx!($op_size, $op_size);
};
}
macro_rules! mov_r_imm {
($bound:ty) => {
fn emulate(
@ -210,6 +223,32 @@ impl<T: CpuStateManager> InstructionHandler<T> for Mov_rm64_r64 {
mov_rm_r!(u64);
}
// MOVZX
pub struct Movzx_r16_rm8;
impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r16_rm8 {
movzx!(u16, u8);
}
pub struct Movzx_r32_rm8;
impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r32_rm8 {
movzx!(u32, u8);
}
pub struct Movzx_r64_rm8;
impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r64_rm8 {
movzx!(u64, u8);
}
pub struct Movzx_r32_rm16;
impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r32_rm16 {
movzx!(u32, u16);
}
pub struct Movzx_r64_rm16;
impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r64_rm16 {
movzx!(u64, u16);
}
#[cfg(test)]
mod tests {
#![allow(unused_mut)]

View File

@ -518,7 +518,13 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> {
(mov, Mov_rm32_imm32),
(mov, Mov_rm32_r32),
(mov, Mov_rm64_imm32),
(mov, Mov_rm64_r64)
(mov, Mov_rm64_r64),
// MOVZX
(mov, Movzx_r16_rm8),
(mov, Movzx_r32_rm8),
(mov, Movzx_r64_rm8),
(mov, Movzx_r32_rm16),
(mov, Movzx_r64_rm16)
);
handler