mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-03-20 07:58:55 +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:
parent
89008a49cf
commit
5ada3f59c8
@ -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)]
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user