use crate::maps::mem64::Permission;
use crate::tests::helpers;
use crate::*;
#[test]
pub fn test_cmpxchg8b_equal() {
helpers::setup();
let mut emu = emu32();
let code: [u8; 7] = [0x0f, 0xc7, 0x0d, 0x00, 0x10, 0x00, 0x00];
emu.maps
.create_map("data", 0x1000, 0x1000, Permission::READ_WRITE)
.expect("failed to map data");
let mem_val: u64 = 0x1122334455667788;
emu.maps.write_qword(0x1000, mem_val);
emu.regs_mut().set_edx(0x11223344);
emu.regs_mut().set_eax(0x55667788);
emu.regs_mut().set_ecx(0xAABBCCDD);
emu.regs_mut().set_ebx(0xEEFF0011);
emu.load_code_bytes(&code);
emu.step();
assert_eq!(emu.flags().f_zf, true, "ZF should be set");
let new_mem_val = emu.maps.read_qword(0x1000).expect("failed to read memory");
assert_eq!(new_mem_val, 0xAABBCCDDEEFF0011, "Memory should be updated");
}
#[test]
pub fn test_cmpxchg8b_not_equal() {
helpers::setup();
let mut emu = emu32();
let code: [u8; 7] = [0x0f, 0xc7, 0x0d, 0x00, 0x10, 0x00, 0x00];
emu.maps
.create_map("data", 0x1000, 0x1000, Permission::READ_WRITE)
.expect("failed to map data");
let mem_val: u64 = 0x9988776655443322;
emu.maps.write_qword(0x1000, mem_val);
emu.regs_mut().set_edx(0x11223344);
emu.regs_mut().set_eax(0x55667788);
emu.load_code_bytes(&code);
emu.step();
assert_eq!(emu.flags().f_zf, false, "ZF should be clear");
assert_eq!(
emu.regs().get_edx(),
0x99887766,
"EDX should be loaded from memory high"
);
assert_eq!(
emu.regs().get_eax(),
0x55443322,
"EAX should be loaded from memory low"
);
let check_mem = emu.maps.read_qword(0x1000).expect("failed to read memory");
assert_eq!(check_mem, 0x9988776655443322, "Memory should be unchanged");
}
#[test]
pub fn test_cmpxchg16b_equal() {
helpers::setup();
let mut emu = emu64();
let code: [u8; 4] = [0x48, 0x0f, 0xc7, 0x0e];
emu.maps
.create_map("data", 0x1000, 0x1000, Permission::READ_WRITE)
.expect("failed to map data");
emu.regs_mut().rsi = 0x1000;
let mem_val: u128 = 0x112233445566778899AABBCCDDEEFF00;
emu.maps.write_bytes(0x1000, &mem_val.to_le_bytes());
emu.regs_mut().rdx = 0x1122334455667788;
emu.regs_mut().rax = 0x99AABBCCDDEEFF00;
emu.regs_mut().rcx = 0xFFEEDDCCBBAA9988;
emu.regs_mut().rbx = 0x7766554433221100;
emu.load_code_bytes(&code);
emu.step();
assert_eq!(emu.flags().f_zf, true, "ZF should be set");
let new_mem_val = emu
.maps
.read_128bits_le(0x1000)
.expect("failed to read memory");
assert_eq!(
new_mem_val, 0xFFEEDDCCBBAA99887766554433221100,
"Memory should be updated"
);
}
#[test]
pub fn test_cmpxchg16b_not_equal() {
helpers::setup();
let mut emu = emu64();
let code: [u8; 4] = [0x48, 0x0f, 0xc7, 0x0e];
emu.maps
.create_map("data", 0x1000, 0x1000, Permission::READ_WRITE)
.expect("failed to map data");
emu.regs_mut().rsi = 0x1000;
let mem_val: u128 = 0x1234567890ABCDEF1234567890ABCDEF;
emu.maps.write_bytes(0x1000, &mem_val.to_le_bytes());
emu.regs_mut().rdx = 0x0;
emu.regs_mut().rax = 0x0;
emu.load_code_bytes(&code);
emu.step();
assert_eq!(emu.flags().f_zf, false, "ZF should be clear");
assert_eq!(
emu.regs().rdx,
0x1234567890ABCDEF,
"RDX should be loaded from memory high"
);
assert_eq!(
emu.regs().rax,
0x1234567890ABCDEF,
"RAX should be loaded from memory low"
);
let check_mem = emu
.maps
.read_128bits_le(0x1000)
.expect("failed to read memory");
assert_eq!(
check_mem, 0x1234567890ABCDEF1234567890ABCDEF,
"Memory should be unchanged"
);
}