From 70fdacdb63eca772cbfd1e0518f74f38ae780d22 Mon Sep 17 00:00:00 2001 From: xarantolus Date: Sat, 31 Dec 2022 16:30:16 +0100 Subject: [PATCH] Refactor entire JS API to work with bigints --- src/instructions/add.rs | 44 ++++---- src/instructions/and.rs | 4 +- src/instructions/cmp.rs | 28 ++--- src/instructions/div.rs | 14 +-- src/instructions/errors.rs | 14 +++ src/instructions/idiv.rs | 12 +-- src/instructions/imul.rs | 22 ++-- src/instructions/lea.rs | 4 +- src/instructions/macros.rs | 194 +++++++++++++++++----------------- src/instructions/memory.rs | 41 ++++--- src/instructions/mov.rs | 2 +- src/instructions/movsxd.rs | 24 ++--- src/instructions/mul.rs | 10 +- src/instructions/pop.rs | 2 +- src/instructions/push.rs | 6 +- src/instructions/registers.rs | 44 +++++--- src/instructions/shr.rs | 4 +- src/instructions/sub.rs | 20 ++-- src/instructions/test.rs | 18 ++-- src/instructions/tests.rs | 14 +-- 20 files changed, 285 insertions(+), 236 deletions(-) diff --git a/src/instructions/add.rs b/src/instructions/add.rs index 0445a86..54a9074 100644 --- a/src/instructions/add.rs +++ b/src/instructions/add.rs @@ -1778,11 +1778,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x0); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x80000000u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_PF | FLAG_SF; FLAG_CF | FLAG_ZF | FLAG_OF) ]; @@ -1823,11 +1823,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x1); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x80000000u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (FLAG_PF | FLAG_SF | FLAG_OF; FLAG_CF | FLAG_ZF) ]; @@ -1838,11 +1838,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x1); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x80000001u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_SF; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_OF) ]; @@ -1853,11 +1853,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x8); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x80000007u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (FLAG_SF | FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF) ]; @@ -1868,11 +1868,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x10); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x8000000fu32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (FLAG_PF | FLAG_SF | FLAG_OF; FLAG_CF | FLAG_ZF) ]; @@ -1883,11 +1883,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x20); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x8000001fu32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (FLAG_SF | FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF) ]; @@ -1898,11 +1898,11 @@ mod tests { write_reg_value!(d; a; EBX; 0x80000000u32); write_reg_value!(q; a; RCX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EBX; 0x0); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_OF; FLAG_SF) ]; @@ -3148,11 +3148,11 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RBX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x800000feu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x800000feu64); }; (FLAG_SF | FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF) ]; @@ -3162,11 +3162,11 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RBX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x800000ffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x800000ffu64); }; (FLAG_PF | FLAG_SF; FLAG_CF | FLAG_ZF | FLAG_OF) ]; @@ -3232,11 +3232,11 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RBX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000002u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000002u64); }; (FLAG_SF | FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF) ]; @@ -3246,11 +3246,11 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RBX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000003u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000003u64); }; (FLAG_PF | FLAG_SF; FLAG_CF | FLAG_ZF | FLAG_OF) ]; diff --git a/src/instructions/and.rs b/src/instructions/and.rs index e636e5b..9652481 100644 --- a/src/instructions/and.rs +++ b/src/instructions/and.rs @@ -636,11 +636,11 @@ mod tests { write_reg_value!(d; a; EAX; 0x80000000u32); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EAX; 0x80000000u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_PF | FLAG_SF; FLAG_CF | FLAG_ZF | FLAG_OF) ]; diff --git a/src/instructions/cmp.rs b/src/instructions/cmp.rs index f361a8c..cb34304 100644 --- a/src/instructions/cmp.rs +++ b/src/instructions/cmp.rs @@ -1080,11 +1080,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x20); write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x20); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF) ]; @@ -1095,11 +1095,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x8); write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x8); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_OF; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF) ]; @@ -1140,11 +1140,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x10); write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x10); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_PF | FLAG_OF; FLAG_CF | FLAG_ZF | FLAG_SF) ]; @@ -1155,11 +1155,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x1); write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x1); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_PF | FLAG_OF; FLAG_CF | FLAG_ZF | FLAG_SF) ]; @@ -1170,11 +1170,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x0); write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x0); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_PF | FLAG_SF; FLAG_CF | FLAG_ZF | FLAG_OF) ]; @@ -1730,11 +1730,11 @@ mod tests { write_reg_value!(q; a; RCX; 0x1000); write_reg_value!(q; a; RBX; 0); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EAX; 0x0); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_CF | FLAG_PF | FLAG_SF | FLAG_OF; FLAG_ZF) ]; @@ -1778,11 +1778,11 @@ mod tests { write_reg_value!(q; a; RCX; 0x1000); write_reg_value!(q; a; RBX; 0); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; EAX; 0x1); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_CF | FLAG_SF | FLAG_OF; FLAG_PF | FLAG_ZF) ]; diff --git a/src/instructions/div.rs b/src/instructions/div.rs index cb3fb24..d7841ab 100644 --- a/src/instructions/div.rs +++ b/src/instructions/div.rs @@ -28,7 +28,7 @@ impl Axecutor { fn instr_div_rm8(&mut self, i: Instruction) -> Result<(), AxError> { debug_assert_eq!(i.code(), Div_rm8); - let ax = self.reg_read_16(AX); + let ax = self.reg_read_16(AX) as u16; let op = self.instruction_operand(i, 0)?; let src_val = match op { @@ -46,8 +46,8 @@ impl Axecutor { let (quotient, remainder) = (ax / src_val, ax % src_val); - self.reg_write_8(AL, quotient as u8); - self.reg_write_8(AH, remainder as u8); + self.reg_write_8(AL, quotient as u8 as u64); + self.reg_write_8(AH, remainder as u8 as u64); Ok(()) } @@ -77,8 +77,8 @@ impl Axecutor { let (quotient, remainder) = (dst_val / src_val, dst_val % src_val); - self.reg_write_16(AX, quotient as u16); - self.reg_write_16(DX, remainder as u16); + self.reg_write_16(AX, quotient as u16 as u64); + self.reg_write_16(DX, remainder as u16 as u64); Ok(()) } @@ -108,8 +108,8 @@ impl Axecutor { let (quotient, remainder) = (dst_val / src_val, dst_val % src_val); - self.reg_write_32(EAX, quotient as u32); - self.reg_write_32(EDX, remainder as u32); + self.reg_write_32(EAX, quotient as u32 as u64); + self.reg_write_32(EDX, remainder as u32 as u64); Ok(()) } diff --git a/src/instructions/errors.rs b/src/instructions/errors.rs index d4b1c90..ce2f508 100644 --- a/src/instructions/errors.rs +++ b/src/instructions/errors.rs @@ -165,6 +165,20 @@ macro_rules! fatal_error { }}; } +#[macro_export] +macro_rules! assert_fatal { + ($cond:expr, $message:expr, $($arg:tt)*) => {{ + if !($cond) { + crate::fatal_error!($message, $($arg)*); + } + }}; + ($cond:expr, $message:expr) => {{ + if !($cond) { + crate::fatal_error!($message); + } + }}; +} + #[macro_export] macro_rules! opcode_unimplemented { ($message:expr) => {{ diff --git a/src/instructions/idiv.rs b/src/instructions/idiv.rs index e8642c2..2a8f154 100644 --- a/src/instructions/idiv.rs +++ b/src/instructions/idiv.rs @@ -46,8 +46,8 @@ impl Axecutor { let (quotient, remainder) = (ax / src_val, ax % src_val); - self.reg_write_8(AL, quotient as u8); - self.reg_write_8(AH, remainder as u8); + self.reg_write_8(AL, quotient as u8 as u64); + self.reg_write_8(AH, remainder as u8 as u64); Ok(()) } @@ -77,8 +77,8 @@ impl Axecutor { let (quotient, remainder) = (dst_val / src_val, dst_val % src_val); - self.reg_write_16(AX, quotient as u16); - self.reg_write_16(DX, remainder as u16); + self.reg_write_16(AX, quotient as u16 as u64); + self.reg_write_16(DX, remainder as u16 as u64); Ok(()) } @@ -109,8 +109,8 @@ impl Axecutor { let (quotient, remainder) = (dst_val / src_val, dst_val % src_val); - self.reg_write_32(EAX, quotient as u32); - self.reg_write_32(EDX, remainder as u32); + self.reg_write_32(EAX, quotient as u32 as u64); + self.reg_write_32(EDX, remainder as u32 as u64); Ok(()) } diff --git a/src/instructions/imul.rs b/src/instructions/imul.rs index c565f6a..2ef0770 100644 --- a/src/instructions/imul.rs +++ b/src/instructions/imul.rs @@ -55,7 +55,7 @@ impl Axecutor { let (result, overflow) = src_value.overflowing_mul(imm_value); - self.reg_write_16(dest_op.into(), result as u16); + self.reg_write_16(dest_op.into(), result as u16 as u64); if overflow { self.set_flags_u8(FLAG_CF | FLAG_OF, 0, 0); @@ -90,7 +90,7 @@ impl Axecutor { let (result, overflow) = src_value.overflowing_mul(imm_value); - self.reg_write_32(dest_op.into(), result as u32); + self.reg_write_32(dest_op.into(), result as u32 as u64); if overflow { self.set_flags_u8(FLAG_CF | FLAG_OF, 0, 0); @@ -160,7 +160,7 @@ impl Axecutor { let (result, overflow) = src_value.overflowing_mul(imm_value); - self.reg_write_16(dest_op.into(), result as u16); + self.reg_write_16(dest_op.into(), result as u16 as u64); if overflow { self.set_flags_u8(FLAG_CF | FLAG_OF, 0, 0); @@ -195,7 +195,7 @@ impl Axecutor { let (result, overflow) = src_value.overflowing_mul(imm_value); - self.reg_write_32(dest_op.into(), result as u32); + self.reg_write_32(dest_op.into(), result as u32 as u64); if overflow { self.set_flags_u8(FLAG_CF | FLAG_OF, 0, 0); @@ -259,7 +259,7 @@ impl Axecutor { let result = (dst_val as i16).wrapping_mul(src_val as i16); - self.reg_write_16(AX, result as u16); + self.reg_write_16(AX, result as u16 as u64); self.set_flags_u8( if result >> 7 != 0 && result >> 7 != -1 { @@ -296,8 +296,8 @@ impl Axecutor { let result = (dst_val as i32).wrapping_mul(src_val as i32); - self.reg_write_16(AX, result as u16); - self.reg_write_16(DX, (result >> 16) as u16); + self.reg_write_16(AX, result as u16 as u64); + self.reg_write_16(DX, (result >> 16) as u16 as u64); self.set_flags_u16( if result >> 15 != 0 && result >> 15 != -1 { @@ -334,8 +334,8 @@ impl Axecutor { let result = (dst_val as i64).wrapping_mul(src_val as i64); - self.reg_write_32(EAX, result as u32); - self.reg_write_32(EDX, (result >> 32) as u32); + self.reg_write_32(EAX, result as u32 as u64); + self.reg_write_32(EDX, (result >> 32) as u32 as u64); self.set_flags_u32( if result >> 31 != 0 && result >> 31 != -1 { @@ -413,7 +413,7 @@ impl Axecutor { let result = (dst_val as i32).wrapping_mul(src_val as i32); - self.reg_write_16(dest_op.into(), result as u16); + self.reg_write_16(dest_op.into(), result as u16 as u64); self.set_flags_u16( if result >> 15 != 0 && result >> 15 != -1 { @@ -453,7 +453,7 @@ impl Axecutor { let result = (dst_val as i64).wrapping_mul(src_val as i64); - self.reg_write_32(dest_op.into(), result as u32); + self.reg_write_32(dest_op.into(), result as u32 as u64); self.set_flags_u32( if result >> 31 != 0 && result >> 31 != -1 { diff --git a/src/instructions/lea.rs b/src/instructions/lea.rs index 04bf36f..6d37c9a 100644 --- a/src/instructions/lea.rs +++ b/src/instructions/lea.rs @@ -35,7 +35,7 @@ impl Axecutor { let dest = dest.into(); - self.reg_write_16(dest, src_addr as u16); + self.reg_write_16(dest, src_addr as u16 as u64); Ok(()) } @@ -54,7 +54,7 @@ impl Axecutor { let dest = dest.into(); - self.reg_write_32(dest, src_addr as u32); + self.reg_write_32(dest, src_addr as u32 as u64); Ok(()) } diff --git a/src/instructions/macros.rs b/src/instructions/macros.rs index 9b55de6..2898adb 100644 --- a/src/instructions/macros.rs +++ b/src/instructions/macros.rs @@ -21,21 +21,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_8(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_8(self.mem_addr(m), result)?; + self.mem_write_8(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_8(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(r, result); + self.reg_write_8(r, result as u64); } Ok(()) } @@ -62,21 +62,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u16); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u16); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -103,21 +103,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u32); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u32); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -185,21 +185,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -226,21 +226,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -267,7 +267,7 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_64(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u64(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { @@ -277,7 +277,7 @@ impl Axecutor { } Operand::Register(r) => { let dest_val = self.reg_read_64(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u64(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { @@ -308,19 +308,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_8(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u8, src_val as u8); self.set_flags_u8(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_8(self.mem_addr(m), result)?; + self.mem_write_8(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_8(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u8, src_val as u8); self.set_flags_u8(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(r, result); + self.reg_write_8(r, result as u64); } Ok(()) } @@ -347,19 +347,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u16, src_val as u16); self.set_flags_u16(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u16, src_val as u16); self.set_flags_u16(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -386,19 +386,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u32, src_val as u32); self.set_flags_u32(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u32, src_val as u32); self.set_flags_u32(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -517,21 +517,21 @@ impl Axecutor { match src { Operand::Memory(m) => { let src_val = self.mem_read_8(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(dest_reg, result); + self.reg_write_8(dest_reg, result as u64); } Ok(()) } Operand::Register(r) => { let src_val = self.reg_read_8(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val as u8); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(dest_reg, result); + self.reg_write_8(dest_reg, result as u64); } Ok(()) } @@ -557,21 +557,21 @@ impl Axecutor { match src { Operand::Memory(m) => { let src_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u16); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(dest_reg, result); + self.reg_write_16(dest_reg, result as u64); } Ok(()) } Operand::Register(r) => { let src_val = self.reg_read_16(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val as u16); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(dest_reg, result); + self.reg_write_16(dest_reg, result as u64); } Ok(()) } @@ -597,21 +597,21 @@ impl Axecutor { match src { Operand::Memory(m) => { let src_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u32); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(dest_reg, result); + self.reg_write_32(dest_reg, result as u64); } Ok(()) } Operand::Register(r) => { let src_val = self.reg_read_32(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val as u32); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(dest_reg, result); + self.reg_write_32(dest_reg, result as u64); } Ok(()) } @@ -683,10 +683,10 @@ impl Axecutor { let dest = dest.into(); let dest_val = self.reg_read_8(dest); - let result = op(dest_val, src_val); + let result = op(dest_val as u8, src_val as u8); self.set_flags_u8(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(dest, result); + self.reg_write_8(dest, result as u64); } Ok(()) } @@ -711,10 +711,10 @@ impl Axecutor { let dest = dest.into(); let dest_val = self.reg_read_16(dest); - let result = op(dest_val, src_val); + let result = op(dest_val as u16, src_val as u16); self.set_flags_u16(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(dest, result); + self.reg_write_16(dest, result as u64); } Ok(()) } @@ -739,10 +739,10 @@ impl Axecutor { let dest = dest.into(); let dest_val = self.reg_read_32(dest); - let result = op(dest_val, src_val); + let result = op(dest_val as u32, src_val as u32); self.set_flags_u32(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(dest, result); + self.reg_write_32(dest, result as u64); } Ok(()) } @@ -795,7 +795,7 @@ impl Axecutor { let dest = dest.into(); let dest_val = self.reg_read_64(dest); - let result = op(dest_val, src_val); + let result = op(dest_val, src_val as u32); self.set_flags_u64(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { self.reg_write_64(dest, result); @@ -877,21 +877,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_8(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_8(self.mem_addr(m), result)?; + self.mem_write_8(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_8(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u8, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(r, result); + self.reg_write_8(r, result as u64); } Ok(()) } @@ -931,21 +931,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -985,21 +985,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val); debug_assert!(flags & NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -1093,19 +1093,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_8(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u8, src_val); self.set_flags_u8(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_8(self.mem_addr(m), result)?; + self.mem_write_8(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_8(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u8, src_val); self.set_flags_u8(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_8(r, result); + self.reg_write_8(r, result as u64); } Ok(()) } @@ -1145,19 +1145,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u16, src_val); self.set_flags_u16(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u16, src_val); self.set_flags_u16(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -1197,19 +1197,19 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let result = op(dest_val, src_val); + let result = op(dest_val as u32, src_val); self.set_flags_u32(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let result = op(dest_val, src_val); + let result = op(dest_val as u32, src_val); self.set_flags_u32(flags_to_set, flags_to_clear, result); if (flags_to_set & NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -1301,21 +1301,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_16(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u16, src_val); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } @@ -1355,21 +1355,21 @@ impl Axecutor { match dest { Operand::Memory(m) => { let dest_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } Operand::Register(r) => { let dest_val = self.reg_read_32(r); - let (result, flags) = op(dest_val, src_val); + let (result, flags) = op(dest_val as u32, src_val); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } @@ -1510,21 +1510,21 @@ impl Axecutor { match dest { Operand::Register(r) => { let src_val = self.reg_read_8(r); - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u8); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.reg_write_8(r, result); + self.reg_write_8(r, result as u64); } Ok(()) } Operand::Memory(m) => { let src_val = self.mem_read_8(self.mem_addr(m))?; - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u8); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u8(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.mem_write_8(self.mem_addr(m), result)?; + self.mem_write_8(self.mem_addr(m), result as u64)?; } Ok(()) } @@ -1549,21 +1549,21 @@ impl Axecutor { match dest { Operand::Register(r) => { let src_val = self.reg_read_16(r); - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u16); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.reg_write_16(r, result); + self.reg_write_16(r, result as u64); } Ok(()) } Operand::Memory(m) => { let src_val = self.mem_read_16(self.mem_addr(m))?; - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u16); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u16(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.mem_write_16(self.mem_addr(m), result)?; + self.mem_write_16(self.mem_addr(m), result as u64)?; } Ok(()) } @@ -1588,21 +1588,21 @@ impl Axecutor { match dest { Operand::Register(r) => { let src_val = self.reg_read_32(r); - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u32); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.reg_write_32(r, result); + self.reg_write_32(r, result as u64); } Ok(()) } Operand::Memory(m) => { let src_val = self.mem_read_32(self.mem_addr(m))?; - let (result, flags) = op(src_val); + let (result, flags) = op(src_val as u32); debug_assert!(flags & crate::instructions::macros::NO_WRITEBACK == 0, "NO_WRITEBACK flag must not be returned by operation lambda, set it as $flags_to_set"); self.set_flags_u32(flags_to_set | flags, flags_to_clear, result); if (flags_to_set & crate::instructions::macros::NO_WRITEBACK) == 0 { - self.mem_write_32(self.mem_addr(m), result)?; + self.mem_write_32(self.mem_addr(m), result as u64)?; } Ok(()) } diff --git a/src/instructions/memory.rs b/src/instructions/memory.rs index a9693cf..259b3f1 100644 --- a/src/instructions/memory.rs +++ b/src/instructions/memory.rs @@ -143,22 +143,22 @@ impl Axecutor { Ok(u64::from_le_bytes(bytes.try_into().unwrap())) } - pub fn mem_read_32(&self, address: u64) -> Result { + pub fn mem_read_32(&self, address: u64) -> Result { let bytes = self.mem_read_bytes(address, 4)?; - Ok(u32::from_le_bytes(bytes.try_into().unwrap())) + Ok(u32::from_le_bytes(bytes.try_into().unwrap()) as u64) } - pub fn mem_read_16(&self, address: u64) -> Result { + pub fn mem_read_16(&self, address: u64) -> Result { let bytes = self.mem_read_bytes(address, 2)?; - Ok(u16::from_le_bytes(bytes.try_into().unwrap())) + Ok(u16::from_le_bytes(bytes.try_into().unwrap()) as u64) } - pub fn mem_read_8(&self, address: u64) -> Result { + pub fn mem_read_8(&self, address: u64) -> Result { let bytes = self.mem_read_bytes(address, 1)?; - Ok(bytes[0]) + Ok(bytes[0] as u64) } // TODO: Currently cannot write consecutive sections of memory @@ -225,16 +225,33 @@ impl Axecutor { self.mem_write_bytes(address, &data.to_le_bytes()) } - pub fn mem_write_32(&mut self, address: u64, data: u32) -> Result<(), AxError> { - self.mem_write_bytes(address, &data.to_le_bytes()) + pub fn mem_write_32(&mut self, address: u64, data: u64) -> Result<(), AxError> { + crate::assert_fatal!( + data <= u32::MAX as u64, + "Could not write {:x} to 4 bytes of memory, value is too large", + data + ); + + self.mem_write_bytes(address, &(data as u32).to_le_bytes()) } - pub fn mem_write_16(&mut self, address: u64, data: u16) -> Result<(), AxError> { - self.mem_write_bytes(address, &data.to_le_bytes()) + pub fn mem_write_16(&mut self, address: u64, data: u64) -> Result<(), AxError> { + crate::assert_fatal!( + data <= u16::MAX as u64, + "Could not write {:x} to 2 bytes of memory, value is too large", + data + ); + self.mem_write_bytes(address, &(data as u16).to_le_bytes()) } - pub fn mem_write_8(&mut self, address: u64, data: u8) -> Result<(), AxError> { - self.mem_write_bytes(address, &[data]) + pub fn mem_write_8(&mut self, address: u64, data: u64) -> Result<(), AxError> { + crate::assert_fatal!( + data <= u8::MAX as u64, + "Could not write {:x} to 1 byte of memory, value is too large", + data + ); + + self.mem_write_bytes(address, &[data as u8]) } #[must_use] diff --git a/src/instructions/mov.rs b/src/instructions/mov.rs index 7c8ca22..5531d47 100644 --- a/src/instructions/mov.rs +++ b/src/instructions/mov.rs @@ -589,7 +589,7 @@ mod tests { }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x9abcdef0u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x9abcdef0u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x9abcdef0u64); }; (0; FLAGS_UNAFFECTED) ]; diff --git a/src/instructions/movsxd.rs b/src/instructions/movsxd.rs index 29bc8d0..8e71a3c 100644 --- a/src/instructions/movsxd.rs +++ b/src/instructions/movsxd.rs @@ -48,11 +48,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x21); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0xffffffff80000000u64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; @@ -273,11 +273,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x1000000000u64); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x7fffffffu64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; @@ -378,11 +378,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x1000); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x7fffffffu64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; @@ -423,11 +423,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x20000000000000u64); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x7fffffffu64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; @@ -498,11 +498,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x41); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x7fffffffu64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; @@ -528,11 +528,11 @@ mod tests { write_reg_value!(q; a; RAX; 0x1000000000000u64); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x7fffffffu64); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x7fffffffu64); }; (0; FLAG_CF | FLAG_PF | FLAG_ZF | FLAG_SF | FLAG_OF) ]; diff --git a/src/instructions/mul.rs b/src/instructions/mul.rs index 824642a..d71fcc7 100644 --- a/src/instructions/mul.rs +++ b/src/instructions/mul.rs @@ -42,7 +42,7 @@ impl Axecutor { let upper = (result >> 8) as u8; - self.reg_write_16(AX, result); + self.reg_write_16(AX, result as u64); self.set_flags_u8( if upper == 0 { 0 } else { FLAG_CF | FLAG_OF }, @@ -73,8 +73,8 @@ impl Axecutor { let upper = (result >> 16) as u16; - self.reg_write_16(AX, result as u16); - self.reg_write_16(DX, upper); + self.reg_write_16(AX, result as u16 as u64); + self.reg_write_16(DX, upper as u64); self.set_flags_u8( if upper == 0 { 0 } else { FLAG_CF | FLAG_OF }, @@ -105,8 +105,8 @@ impl Axecutor { let upper = (result >> 32) as u32; - self.reg_write_32(EAX, result as u32); - self.reg_write_32(EDX, upper); + self.reg_write_32(EAX, result as u32 as u64); + self.reg_write_32(EDX, upper as u64); self.set_flags_u8( if upper == 0 { 0 } else { FLAG_CF | FLAG_OF }, diff --git a/src/instructions/pop.rs b/src/instructions/pop.rs index bcd68f5..c08e25d 100644 --- a/src/instructions/pop.rs +++ b/src/instructions/pop.rs @@ -35,7 +35,7 @@ impl Axecutor { let rsp = self.reg_read_64(Register::RSP.into()) + 2; let value = self.mem_read_16(rsp)?; - self.reg_write_16(reg, value); + self.reg_write_16(reg, value as u64); self.reg_write_64(Register::RSP.into(), rsp); diff --git a/src/instructions/push.rs b/src/instructions/push.rs index 55c3205..a97805e 100644 --- a/src/instructions/push.rs +++ b/src/instructions/push.rs @@ -81,7 +81,7 @@ impl Axecutor { let value = i.immediate16() as u64; let rsp = self.reg_read_64(Register::RSP.into()); - self.mem_write_16(rsp, value as u16)?; + self.mem_write_16(rsp, value)?; self.reg_write_64(Register::RSP.into(), rsp - 2); Ok(()) @@ -138,14 +138,14 @@ impl Axecutor { let value = i.immediate8to16(); let rsp = self.reg_read_64(Register::RSP.into()); - self.mem_write_16(rsp, value as u16)?; + self.mem_write_16(rsp, value as u16 as u64)?; self.reg_write_64(Register::RSP.into(), rsp - 2); } OpKind::Immediate8to32 => { let value = i.immediate8to32(); let rsp = self.reg_read_64(Register::RSP.into()); - self.mem_write_32(rsp, value as u32)?; + self.mem_write_32(rsp, value as u32 as u64)?; self.reg_write_64(Register::RSP.into(), rsp - 4); } OpKind::Immediate8to64 => { diff --git a/src/instructions/registers.rs b/src/instructions/registers.rs index ab422d6..24cfd3b 100644 --- a/src/instructions/registers.rs +++ b/src/instructions/registers.rs @@ -363,7 +363,13 @@ impl SupportedRegister { #[wasm_bindgen] impl Axecutor { - pub fn reg_write_8(&mut self, reg: SupportedRegister, value: u8) { + pub fn reg_write_8(&mut self, reg: SupportedRegister, value: u64) { + assert!( + value <= 0xFF, + "reg_write_8: value {:x} is too large to fit in 8 bits", + value + ); + let r: Register = reg.into(); assert!(r.is_gpr8(), "{:?} is not a valid 8-bit register", r); @@ -375,9 +381,9 @@ impl Axecutor { let reg_value = self.state.registers.get(&qword_register).unwrap().clone(); let result_value: u64 = if is_high { - (reg_value & 0xFFFF_FFFF_FFFF_00FF) | ((value as u64) << 8) + (reg_value & 0xFFFF_FFFF_FFFF_00FF) | (value << 8) } else { - (reg_value & 0xFFFF_FFFF_FFFF_FF00) | (value as u64) + (reg_value & 0xFFFF_FFFF_FFFF_FF00) | value }; self.state.registers.insert(*qword_register, result_value); @@ -392,7 +398,13 @@ impl Axecutor { ); } - pub fn reg_write_16(&mut self, reg: SupportedRegister, value: u16) { + pub fn reg_write_16(&mut self, reg: SupportedRegister, value: u64) { + assert!( + value <= 0xFFFF, + "reg_write_16: value {:x} is too large to fit in 16 bits", + value + ); + let r: Register = reg.into(); assert!(r.is_gpr16(), "{:?} is not a valid 16-bit register", r); @@ -401,7 +413,7 @@ impl Axecutor { let reg_value = self.state.registers.get(&qword_register).unwrap().clone(); - let result_value = (reg_value & 0xFFFF_FFFF_FFFF_0000) | (value as u64); + let result_value = (reg_value & 0xFFFF_FFFF_FFFF_0000) | value; self.state.registers.insert(*qword_register, result_value); debug_log!( @@ -414,7 +426,13 @@ impl Axecutor { ); } - pub fn reg_write_32(&mut self, reg: SupportedRegister, value: u32) { + pub fn reg_write_32(&mut self, reg: SupportedRegister, value: u64) { + assert!( + value <= 0xFFFF_FFFF, + "reg_write_32: value {:x} is too large to fit in 32 bits", + value + ); + let r: Register = reg.into(); assert!(r.is_gpr32(), "{:?} is not a valid 32-bit register", r); @@ -422,7 +440,7 @@ impl Axecutor { let qword_register = REGISTER_TO_QWORD.get(®).unwrap(); // Intentionally cut off the upper 32bit, setting them to zero - let result_value = value as u64; + let result_value = value as u32 as u64; #[allow(unused_variables)] let old = self.state.registers.insert(*qword_register, result_value); @@ -461,7 +479,7 @@ impl Axecutor { ); } - pub fn reg_read_8(&self, reg: SupportedRegister) -> u8 { + pub fn reg_read_8(&self, reg: SupportedRegister) -> u64 { let r: Register = reg.into(); assert!(r.is_gpr8(), "{:?} is not a valid 8-bit register", r); @@ -480,10 +498,10 @@ impl Axecutor { debug_log!("Read value 0x{:x} from {:?}", result_value, reg); - return result_value; + return result_value as u64; } - pub fn reg_read_16(&self, reg: SupportedRegister) -> u16 { + pub fn reg_read_16(&self, reg: SupportedRegister) -> u64 { let r: Register = reg.into(); assert!(r.is_gpr16(), "{:?} is not a valid 16-bit register", r); @@ -492,14 +510,14 @@ impl Axecutor { let reg_value = self.state.registers.get(&qword_register).unwrap().clone(); - let result_value = (reg_value & 0xFFFF) as u16; + let result_value = reg_value & 0xFFFF; debug_log!("Read value 0x{:x} from {:?}", result_value, reg); return result_value; } - pub fn reg_read_32(&self, reg: SupportedRegister) -> u32 { + pub fn reg_read_32(&self, reg: SupportedRegister) -> u64 { let r: Register = reg.into(); assert!(r.is_gpr32(), "{:?} is not a valid 32-bit register", r); @@ -508,7 +526,7 @@ impl Axecutor { let reg_value = self.state.registers.get(&qword_register).unwrap().clone(); - let result_value = (reg_value & 0xFFFF_FFFF) as u32; + let result_value = reg_value & 0xFFFF_FFFF; debug_log!("Read value 0x{:x} from {:?}", result_value, reg); diff --git a/src/instructions/shr.rs b/src/instructions/shr.rs index 99b6bf3..b96e754 100644 --- a/src/instructions/shr.rs +++ b/src/instructions/shr.rs @@ -676,7 +676,7 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); @@ -690,7 +690,7 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x7fffffffu32).unwrap(); + a.mem_write_32(0x1000, 0x7fffffffu64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); diff --git a/src/instructions/sub.rs b/src/instructions/sub.rs index 54f466f..b9473f1 100644 --- a/src/instructions/sub.rs +++ b/src/instructions/sub.rs @@ -2182,11 +2182,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x0); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x80000000u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_CF | FLAG_PF | FLAG_SF | FLAG_OF; FLAG_ZF) ]; @@ -2227,11 +2227,11 @@ mod tests { write_reg_value!(d; a; ECX; 0x1); write_reg_value!(q; a; RBX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(d; a; ECX; 0x80000001u32); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0x80000000u64); }; (FLAG_CF | FLAG_SF | FLAG_OF; FLAG_PF | FLAG_ZF) ]; @@ -3085,7 +3085,7 @@ mod tests { }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffd7u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffd7u64); }; (FLAG_CF | FLAG_PF | FLAG_SF; FLAG_ZF | FLAG_OF) ]; @@ -3099,7 +3099,7 @@ mod tests { }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffcfu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffcfu64); }; (FLAG_CF | FLAG_PF | FLAG_SF; FLAG_ZF | FLAG_OF) ]; @@ -3113,7 +3113,7 @@ mod tests { }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffd0u32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffd0u64); }; (FLAG_CF | FLAG_SF; FLAG_PF | FLAG_ZF | FLAG_OF) ]; @@ -3127,7 +3127,7 @@ mod tests { }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); - assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffdfu32); + assert_eq!(a.mem_read_32(0x1000).unwrap(), 0xffffffdfu64); }; (FLAG_CF | FLAG_SF; FLAG_PF | FLAG_ZF | FLAG_OF) ]; @@ -3165,7 +3165,7 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); @@ -3347,7 +3347,7 @@ mod tests { |a: &mut Axecutor| { write_reg_value!(q; a; RAX; 0x1000); a.mem_init_zero(0x1000, 4).unwrap(); - a.mem_write_32(0x1000, 0x80000000u32).unwrap(); + a.mem_write_32(0x1000, 0x80000000u64).unwrap() }; |a: Axecutor| { assert_reg_value!(q; a; RAX; 0x1000); diff --git a/src/instructions/test.rs b/src/instructions/test.rs index 18c249f..8a74311 100644 --- a/src/instructions/test.rs +++ b/src/instructions/test.rs @@ -42,13 +42,13 @@ impl Axecutor { let src_val = match src { Operand::Register(r) => self.reg_read_8(r), _ => fatal_error!("Invalid source operand {:?} for TEST r/m8, r8", src), - }; + } as u8; let dest_val = match dest { Operand::Register(r) => self.reg_read_8(r), Operand::Memory(m) => self.mem_read_8(self.mem_addr(m))?, _ => fatal_error!("Invalid destination operand {:?} for TEST r/m8, r8", dest), - }; + } as u8; let result = dest_val & src_val; @@ -68,13 +68,13 @@ impl Axecutor { let src_val = match src { Operand::Register(r) => self.reg_read_16(r), _ => fatal_error!("Invalid source operand {:?} for TEST r/m16, r16", src), - }; + } as u16; let dest_val = match dest { Operand::Register(r) => self.reg_read_16(r), Operand::Memory(m) => self.mem_read_16(self.mem_addr(m))?, _ => fatal_error!("Invalid destination operand {:?} for TEST r/m16, r16", dest), - }; + } as u16; let result = dest_val & src_val; @@ -94,13 +94,13 @@ impl Axecutor { let src_val = match src { Operand::Register(r) => self.reg_read_32(r), _ => fatal_error!("Invalid source operand {:?} for TEST r/m32, r32", src), - }; + } as u32; let dest_val = match dest { Operand::Register(r) => self.reg_read_32(r), Operand::Memory(m) => self.mem_read_32(self.mem_addr(m))?, _ => fatal_error!("Invalid destination operand {:?} for TEST r/m32, r32", dest), - }; + } as u32; let result = dest_val & src_val; @@ -190,7 +190,7 @@ impl Axecutor { Operand::Register(r) => self.reg_read_8(r), Operand::Memory(m) => self.mem_read_8(self.mem_addr(m))?, _ => fatal_error!("Invalid destination operand {:?} for TEST r/m8, imm8", dest), - }; + } as u8; let result = dest_val & src_val; @@ -231,7 +231,7 @@ impl Axecutor { "Invalid destination operand {:?} for TEST r/m16, imm16", dest ), - }; + } as u16; let result = dest_val & src_val; @@ -262,7 +262,7 @@ impl Axecutor { "Invalid destination operand {:?} for TEST r/m32, imm32", dest ), - }; + } as u32; let result = dest_val & src_val; diff --git a/src/instructions/tests.rs b/src/instructions/tests.rs index 207ed53..6d2517f 100644 --- a/src/instructions/tests.rs +++ b/src/instructions/tests.rs @@ -101,7 +101,7 @@ macro_rules! assert_reg_value { [b; $axecutor:expr; $reg:expr; $value:expr] => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr8(), "Register must be 8 bit wide"); - let val = $axecutor.reg_read_8(wrap); + let val = $axecutor.reg_read_8(wrap) as u8; assert_eq!( &val, &$value, "expected register {:?} to have value {:?}, but got {}", @@ -111,7 +111,7 @@ macro_rules! assert_reg_value { [w; $axecutor:expr; $reg:expr; $value:expr] => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr16(), "Register must be 16 bit wide"); - let val = $axecutor.reg_read_16(wrap); + let val = $axecutor.reg_read_16(wrap) as u16; assert_eq!( &val, &$value, "expected register {:?} to have value {:?}, but got {}", @@ -121,7 +121,7 @@ macro_rules! assert_reg_value { [d; $axecutor:expr; $reg:expr; $value:expr] => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr32(), "Register must be 32 bit wide"); - let val = $axecutor.reg_read_32(wrap); + let val = $axecutor.reg_read_32(wrap) as u32; assert_eq!( &val, &$value, "expected register {:?} to have value {:?}, but got {}", @@ -146,22 +146,22 @@ macro_rules! write_reg_value { (b; $axecutor:expr; $reg:expr; $value:expr) => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr8(), "Register must be 8 bit wide"); - $axecutor.reg_write_8(wrap, $value); + $axecutor.reg_write_8(wrap, $value as u64); }; (w; $axecutor:expr; $reg:expr; $value:expr) => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr16(), "Register must be 16 bit wide"); - $axecutor.reg_write_16(wrap, $value); + $axecutor.reg_write_16(wrap, $value as u64); }; (d; $axecutor:expr; $reg:expr; $value:expr) => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr32(), "Register must be 32 bit wide"); - $axecutor.reg_write_32(wrap, $value); + $axecutor.reg_write_32(wrap, $value as u64); }; (q; $axecutor:expr; $reg:expr; $value:expr) => { let wrap = SupportedRegister::from($reg); assert!($reg.is_gpr64(), "Register must be 64 bit wide"); - $axecutor.reg_write_64(wrap, $value); + $axecutor.reg_write_64(wrap, $value as u64); }; }