mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
@@ -74,21 +74,27 @@ macro_rules! mov_rm_imm {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! mov_r_rm {
|
macro_rules! movzx {
|
||||||
($bound:ty) => {
|
($src_op_size:ty, $dest_op_size:ty) => {
|
||||||
fn emulate(
|
fn emulate(
|
||||||
&self,
|
&self,
|
||||||
insn: &Instruction,
|
insn: &Instruction,
|
||||||
state: &mut T,
|
state: &mut T,
|
||||||
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
||||||
) -> Result<(), EmulationError<Exception>> {
|
) -> Result<(), EmulationError<Exception>> {
|
||||||
let src_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform)
|
let src_value = get_op(
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
&insn,
|
||||||
|
1,
|
||||||
|
std::mem::size_of::<$src_op_size>(),
|
||||||
|
state,
|
||||||
|
platform,
|
||||||
|
)
|
||||||
|
.map_err(EmulationError::PlatformEmulationError)?;
|
||||||
|
|
||||||
set_op(
|
set_op(
|
||||||
&insn,
|
&insn,
|
||||||
0,
|
0,
|
||||||
std::mem::size_of::<$bound>(),
|
std::mem::size_of::<$dest_op_size>(),
|
||||||
state,
|
state,
|
||||||
platform,
|
platform,
|
||||||
src_value,
|
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 {
|
macro_rules! mov_r_imm {
|
||||||
($bound:ty) => {
|
($bound:ty) => {
|
||||||
fn emulate(
|
fn emulate(
|
||||||
@@ -210,6 +223,32 @@ impl<T: CpuStateManager> InstructionHandler<T> for Mov_rm64_r64 {
|
|||||||
mov_rm_r!(u64);
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(unused_mut)]
|
#![allow(unused_mut)]
|
||||||
|
|||||||
@@ -518,7 +518,13 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> {
|
|||||||
(mov, Mov_rm32_imm32),
|
(mov, Mov_rm32_imm32),
|
||||||
(mov, Mov_rm32_r32),
|
(mov, Mov_rm32_r32),
|
||||||
(mov, Mov_rm64_imm32),
|
(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
|
handler
|
||||||
|
|||||||
Reference in New Issue
Block a user