use crate::*;
#[test]
fn test_rol_al_1() {
let code = [
0xd0, 0xc0, 0xf4, ];
let mut emu = emu64();
emu.regs_mut().rax = 0x42; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x84, "AL: 0x42 ROL 1 = 0x84");
assert!(!emu.flags().f_cf, "CF: receives MSB (was 0)");
assert!(emu.flags().f_of, "OF: CF XOR new MSB = 0 XOR 1 = 1");
}
#[test]
fn test_rol_al_1_with_msb() {
let code = [
0xd0, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x81; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x03, "AL: 0x81 ROL 1 = 0x03 (MSB rotates to LSB)");
assert!(emu.flags().f_cf, "CF: receives MSB (was 1)");
}
#[test]
fn test_rol_al_cl() {
let code = [
0xd2, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x01; emu.regs_mut().rcx = 0x04; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x10, "AL: 0x01 ROL 4 = 0x10");
assert!(!emu.flags().f_cf, "CF: last bit rotated was 0");
}
#[test]
fn test_rol_al_imm8() {
let code = [
0xc0, 0xc0, 0x03, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x11; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x88, "AL: 0x11 ROL 3 = 0x88");
assert!(!emu.flags().f_cf, "CF: last bit rotated was 0");
}
#[test]
fn test_rol_full_rotation_8bit() {
let code = [
0xc0, 0xc0, 0x08, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x42;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x42, "AL: full rotation returns to original");
}
#[test]
fn test_rol_count_masked_8bit() {
let code = [
0xd2, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x11;
emu.regs_mut().rcx = 0x1B; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x88, "AL: rotation count masked");
}
#[test]
fn test_rol_count_zero_preserves_flags() {
let code = [
0xc0, 0xc0, 0x00, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x42;
emu.load_code_bytes(&code);
emu.flags_mut().load(0x2 | (1 << flags::F_CF) | (1 << flags::F_ZF) | (1 << flags::F_OF));
let initial_flags = emu.flags().dump();
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x42, "AL: unchanged");
assert_eq!(emu.flags().dump() & (flags::F_CF | flags::F_ZF | flags::F_OF),
initial_flags & (flags::F_CF | flags::F_ZF | flags::F_OF),
"Flags preserved");
}
#[test]
fn test_rol_bl() {
let code = [
0xd0, 0xc3, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rbx = 0xC5; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rbx & 0xFF, 0x8B, "BL: 0xC5 ROL 1 = 0x8B");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_cl_reg() {
let code = [
0xc0, 0xc1, 0x02, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rcx = 0x33; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx & 0xFF, 0xCC, "CL: 0x33 ROL 2 = 0xCC");
}
#[test]
fn test_rol_dl() {
let code = [
0xd2, 0xc2, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdx = 0x0F;
emu.regs_mut().rcx = 0x04;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdx & 0xFF, 0xF0, "DL: 0x0F ROL 4 = 0xF0");
}
#[test]
fn test_rol_ax_1() {
let code = [
0x66, 0xd1, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x4321; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0x8642, "AX: 0x4321 ROL 1 = 0x8642");
assert!(!emu.flags().f_cf, "CF: MSB was 0");
}
#[test]
fn test_rol_ax_cl() {
let code = [
0x66, 0xd3, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x1234;
emu.regs_mut().rcx = 0x04;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0x2341, "AX: 0x1234 ROL 4 = 0x2341");
}
#[test]
fn test_rol_ax_imm8() {
let code = [
0x66, 0xc1, 0xc0, 0x08, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x1234;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0x3412, "AX: 0x1234 ROL 8 = 0x3412 (byte swap)");
}
#[test]
fn test_rol_ax_full_rotation() {
let code = [
0x66, 0xc1, 0xc0, 0x10, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x1234;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0x1234, "AX: full rotation returns to original");
}
#[test]
fn test_rol_bx() {
let code = [
0x66, 0xd1, 0xc3, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rbx = 0x8000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rbx & 0xFFFF, 0x0001, "BX: 0x8000 ROL 1 = 0x0001");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_cx() {
let code = [
0x66, 0xc1, 0xc1, 0x04, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rcx = 0xABCD;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx & 0xFFFF, 0xBCDA, "CX: 0xABCD ROL 4 = 0xBCDA");
}
#[test]
fn test_rol_dx_cl() {
let code = [
0x66, 0xd3, 0xc2, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdx = 0x00FF;
emu.regs_mut().rcx = 0x08;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdx & 0xFFFF, 0xFF00, "DX: 0x00FF ROL 8 = 0xFF00");
}
#[test]
fn test_rol_eax_1() {
let code = [
0xd1, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x43218765;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFFFFFF, 0x86430ECA, "EAX: 0x43218765 ROL 1 = 0x86430ECA");
}
#[test]
fn test_rol_eax_cl() {
let code = [
0xd3, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x12345678;
emu.regs_mut().rcx = 0x08;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFFFFFF, 0x34567812, "EAX: 0x12345678 ROL 8 = 0x34567812");
}
#[test]
fn test_rol_eax_imm8() {
let code = [
0xc1, 0xc0, 0x10, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFFFFFF, 0x56781234, "EAX: 0x12345678 ROL 16 = 0x56781234");
}
#[test]
fn test_rol_eax_full_rotation() {
let code = [
0xc1, 0xc0, 0x20, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFFFFFF, 0x12345678, "EAX: full rotation returns to original");
}
#[test]
fn test_rol_ebx() {
let code = [
0xd1, 0xc3, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rbx = 0x80000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rbx & 0xFFFFFFFF, 0x00000001, "EBX: 0x80000000 ROL 1 = 0x00000001");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_ecx() {
let code = [
0xc1, 0xc1, 0x04, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rcx = 0xABCDEF01;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx & 0xFFFFFFFF, 0xBCDEF01A, "ECX: 0xABCDEF01 ROL 4 = 0xBCDEF01A");
}
#[test]
fn test_rol_edx_cl() {
let code = [
0xd3, 0xc2, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdx = 0x000000FF;
emu.regs_mut().rcx = 0x18; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdx & 0xFFFFFFFF, 0xFF000000, "EDX: 0x000000FF ROL 24 = 0xFF000000");
}
#[test]
fn test_rol_esi() {
let code = [
0xd1, 0xc6, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rsi = 0x40000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rsi & 0xFFFFFFFF, 0x80000000, "ESI: 0x40000000 ROL 1 = 0x80000000");
}
#[test]
fn test_rol_edi() {
let code = [
0xc1, 0xc7, 0x0C, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdi = 0x12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdi & 0xFFFFFFFF, 0x45678123, "EDI: 0x12345678 ROL 12 = 0x45678123");
}
#[test]
fn test_rol_rax_1() {
let code = [
0x48, 0xd1, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x4321876543218765;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x86430ECA86430ECA, "RAX: ROL 1");
}
#[test]
fn test_rol_rax_cl() {
let code = [
0x48, 0xd3, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.regs_mut().rcx = 0x08;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x3456789ABCDEF012, "RAX: 0x123456789ABCDEF0 ROL 8");
}
#[test]
fn test_rol_rax_imm8() {
let code = [
0x48, 0xc1, 0xc0, 0x10, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x56789ABCDEF01234, "RAX: 0x123456789ABCDEF0 ROL 16");
}
#[test]
fn test_rol_rax_32bits() {
let code = [
0x48, 0xc1, 0xc0, 0x20, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x9ABCDEF012345678, "RAX: ROL 32 swaps high/low dwords");
}
#[test]
fn test_rol_rax_full_rotation() {
let code = [
0x48, 0xc1, 0xc0, 0x40, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x123456789ABCDEF0, "RAX: full rotation returns to original");
}
#[test]
fn test_rol_rbx() {
let code = [
0x48, 0xd1, 0xc3, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rbx = 0x8000000000000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rbx, 0x0000000000000001, "RBX: 0x8000000000000000 ROL 1 = 0x0000000000000001");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_rcx() {
let code = [
0x48, 0xc1, 0xc1, 0x04, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rcx = 0xABCDEF0123456789;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx, 0xBCDEF0123456789A, "RCX: ROL 4");
}
#[test]
fn test_rol_rdx_cl() {
let code = [
0x48, 0xd3, 0xc2, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdx = 0x00000000000000FF;
emu.regs_mut().rcx = 0x38; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdx, 0xFF00000000000000, "RDX: ROL 56");
}
#[test]
fn test_rol_rsi() {
let code = [
0x48, 0xd1, 0xc6, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rsi = 0x4000000000000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rsi, 0x8000000000000000, "RSI: ROL 1");
}
#[test]
fn test_rol_rdi() {
let code = [
0x48, 0xc1, 0xc7, 0x0C, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().rdi = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rdi, 0x456789ABCDEF0123, "RDI: ROL 12");
}
#[test]
fn test_rol_r8() {
let code = [
0x49, 0xd1, 0xc0, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().r8 = 0xFEDCBA9876543210;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r8, 0xFDB97530ECA86421, "R8: ROL 1");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_r9_cl() {
let code = [
0x49, 0xd3, 0xc1, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().r9 = 0x0123456789ABCDEF;
emu.regs_mut().rcx = 0x10; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r9, 0x456789ABCDEF0123, "R9: ROL 16");
}
#[test]
fn test_rol_r10_imm8() {
let code = [
0x49, 0xc1, 0xc2, 0x08, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().r10 = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r10, 0x3456789ABCDEF012, "R10: ROL 8");
}
#[test]
fn test_rol_r15() {
let code = [
0x49, 0xd1, 0xc7, 0xf4,
];
let mut emu = emu64();
emu.regs_mut().r15 = 0x1111111111111111;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r15, 0x2222222222222222, "R15: ROL 1");
}
#[test]
fn test_rol_mem8() {
let DATA_ADDR = 0x7000;
let code = [
0xd0, 0x04, 0x25, (DATA_ADDR & 0xFF) as u8,
((DATA_ADDR >> 8) & 0xFF) as u8,
((DATA_ADDR >> 16) & 0xFF) as u8,
((DATA_ADDR >> 24) & 0xFF) as u8,
0xf4,
];
let mut emu = emu64();
emu.maps.create_map("test_data", 0x7000, 0x1000, crate::maps::mem64::Permission::READ_WRITE).expect("failed to map test_data");
emu.load_code_bytes(&code);
emu.maps.write_byte(DATA_ADDR, 0x81);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_byte(DATA_ADDR).unwrap(), 0x03, "Memory: 0x81 ROL 1 = 0x03");
assert!(emu.flags().f_cf, "CF: MSB was 1");
}
#[test]
fn test_rol_mem16() {
let DATA_ADDR = 0x7000;
let code = [
0x66, 0xc1, 0x04, 0x25, (DATA_ADDR & 0xFF) as u8,
((DATA_ADDR >> 8) & 0xFF) as u8,
((DATA_ADDR >> 16) & 0xFF) as u8,
((DATA_ADDR >> 24) & 0xFF) as u8,
0x04, 0xf4,
];
let mut emu = emu64();
emu.maps.create_map("test_data", 0x7000, 0x1000, crate::maps::mem64::Permission::READ_WRITE).expect("failed to map test_data");
emu.load_code_bytes(&code);
emu.maps.write_word(DATA_ADDR, 0x1234);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_word(DATA_ADDR).unwrap(), 0x2341, "Memory: 0x1234 ROL 4 = 0x2341");
}
#[test]
fn test_rol_mem32() {
let DATA_ADDR = 0x7000;
let code = [
0xd3, 0x04, 0x25, (DATA_ADDR & 0xFF) as u8,
((DATA_ADDR >> 8) & 0xFF) as u8,
((DATA_ADDR >> 16) & 0xFF) as u8,
((DATA_ADDR >> 24) & 0xFF) as u8,
0xf4,
];
let mut emu = emu64();
emu.maps.create_map("test_data", 0x7000, 0x1000, crate::maps::mem64::Permission::READ_WRITE).expect("failed to map test_data");
emu.regs_mut().rcx = 0x08;
emu.load_code_bytes(&code);
emu.maps.write_dword(DATA_ADDR, 0x12345678);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_dword(DATA_ADDR).unwrap(), 0x34567812, "Memory: 0x12345678 ROL 8 = 0x34567812");
}
#[test]
fn test_rol_mem64() {
let DATA_ADDR = 0x7000;
let code = [
0x48, 0xc1, 0x04, 0x25, (DATA_ADDR & 0xFF) as u8,
((DATA_ADDR >> 8) & 0xFF) as u8,
((DATA_ADDR >> 16) & 0xFF) as u8,
((DATA_ADDR >> 24) & 0xFF) as u8,
0x10, 0xf4,
];
let mut emu = emu64();
emu.maps.create_map("test_data", 0x7000, 0x1000, crate::maps::mem64::Permission::READ_WRITE).expect("failed to map test_data");
emu.load_code_bytes(&code);
emu.maps.write_qword(DATA_ADDR, 0x123456789ABCDEF0);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(DATA_ADDR).unwrap(), 0x56789ABCDEF01234, "Memory: ROL 16");
}