use crate::*;
#[test]
fn test_inc_al_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4]; emu.regs_mut().rax = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 11, "INC AL: 10 + 1 = 11");
assert!(!emu.flags().f_zf, "ZF should be clear");
}
#[test]
fn test_inc_al_zero_result() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0, "INC AL: 0xFF + 1 = 0x00 (wraps)");
assert!(emu.flags().f_zf, "ZF should be set (result = 0)");
}
#[test]
fn test_inc_al_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0x7F;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x80, "INC AL: 0x7F + 1 = 0x80");
assert!(emu.flags().f_of, "OF should be set (signed overflow)");
assert!(emu.flags().f_sf, "SF should be set (result negative)");
}
#[test]
fn test_inc_al_preserves_cf() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFF;
emu.flags_mut().load(0x2 | flags::F_CF); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0);
assert!(emu.flags().f_cf, "CF should be preserved (still set)");
}
#[test]
fn test_inc_al_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0x03, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
emu.load_code_bytes(&code);
emu.maps.write_byte(DATA_ADDR, 42);
emu.run(None).unwrap();
assert_eq!(
emu.maps.read_byte(DATA_ADDR).unwrap(),
43,
"INC [RBX]: 42 + 1 = 43"
);
}
#[test]
fn test_dec_al_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4]; emu.regs_mut().rax = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 9, "DEC AL: 10 - 1 = 9");
assert!(!emu.flags().f_zf, "ZF should be clear");
}
#[test]
fn test_dec_al_zero() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x00;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0xFF, "DEC AL: 0x00 - 1 = 0xFF");
assert!(emu.flags().f_sf, "SF should be set (result negative)");
}
#[test]
fn test_dec_al_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x80; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x7F, "DEC AL: 0x80 - 1 = 0x7F");
assert!(emu.flags().f_of, "OF should be set (signed underflow)");
assert!(!emu.flags().f_sf, "SF should be clear (result positive)");
}
#[test]
fn test_dec_al_preserves_cf() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x80;
emu.flags_mut().load(0x2); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert!(!emu.flags().f_cf, "CF should be preserved (still clear)");
}
#[test]
fn test_dec_al_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0x0b, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
emu.load_code_bytes(&code);
emu.maps.write_byte(DATA_ADDR, 42);
emu.run(None).unwrap();
assert_eq!(
emu.maps.read_byte(DATA_ADDR).unwrap(),
41,
"DEC [RBX]: 42 - 1 = 41"
);
}
#[test]
fn test_inc_ax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0xc0, 0xf4]; emu.regs_mut().rax = 0x1234;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(
emu.regs().rax & 0xFFFF,
0x1235,
"INC AX: 0x1234 + 1 = 0x1235"
);
}
#[test]
fn test_inc_ax_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0, "INC AX: 0xFFFF + 1 = 0");
assert!(emu.flags().f_zf, "ZF should be set");
}
#[test]
fn test_inc_ax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0x03, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
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(), 0x1235);
}
#[test]
fn test_dec_ax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0xc8, 0xf4]; emu.regs_mut().rax = 0x1234;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(
emu.regs().rax & 0xFFFF,
0x1233,
"DEC AX: 0x1234 - 1 = 0x1233"
);
}
#[test]
fn test_dec_ax_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0xc8, 0xf4];
emu.regs_mut().rax = 0x0000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(
emu.regs().rax & 0xFFFF,
0xFFFF,
"DEC AX: 0x0000 - 1 = 0xFFFF"
);
assert!(emu.flags().f_sf, "SF should be set");
}
#[test]
fn test_dec_ax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xff, 0x0b, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
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(), 0x1233);
}
#[test]
fn test_inc_eax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc0, 0xf4]; emu.regs_mut().rax = 0x12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x12345679, "INC EAX: 0x12345678 + 1");
}
#[test]
fn test_inc_eax_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFFFFFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0, "INC EAX: 0xFFFFFFFF + 1 = 0");
assert!(emu.flags().f_zf, "ZF should be set");
}
#[test]
fn test_inc_eax_signed_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc0, 0xf4];
emu.regs_mut().rax = 0x7FFFFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x80000000);
assert!(emu.flags().f_of, "OF should be set (signed overflow)");
}
#[test]
fn test_inc_eax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0x03, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
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(), 0x12345679);
}
#[test]
fn test_dec_eax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc8, 0xf4]; emu.regs_mut().rax = 0x12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x12345677, "DEC EAX: 0x12345678 - 1");
}
#[test]
fn test_dec_eax_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc8, 0xf4];
emu.regs_mut().rax = 0x00000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(
emu.regs().rax,
0xFFFFFFFF,
"DEC EAX: 0x00000000 - 1 = 0xFFFFFFFF"
);
assert!(emu.flags().f_sf, "SF should be set");
}
#[test]
fn test_dec_eax_signed_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc8, 0xf4];
emu.regs_mut().rax = 0x80000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x7FFFFFFF);
assert!(emu.flags().f_of, "OF should be set (signed underflow)");
assert!(!emu.flags().f_sf, "SF should be clear");
}
#[test]
fn test_dec_eax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0x0b, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
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(), 0x12345677);
}
#[test]
fn test_inc_rax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc0, 0xf4]; emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x123456789ABCDEF1, "INC RAX");
}
#[test]
fn test_inc_rax_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFFFFFFFFFFFFFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0, "INC RAX: max + 1 = 0");
assert!(emu.flags().f_zf, "ZF should be set");
}
#[test]
fn test_inc_rax_signed_overflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc0, 0xf4];
emu.regs_mut().rax = 0x7FFFFFFFFFFFFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x8000000000000000);
assert!(emu.flags().f_of, "OF should be set (signed overflow)");
assert!(emu.flags().f_sf, "SF should be set");
}
#[test]
fn test_inc_rax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0x03, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
emu.load_code_bytes(&code);
emu.maps.write_qword(DATA_ADDR, 0xFEDCBA9876543210);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(DATA_ADDR).unwrap(), 0xFEDCBA9876543211);
}
#[test]
fn test_dec_rax_basic() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc8, 0xf4]; emu.regs_mut().rax = 0x123456789ABCDEF0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x123456789ABCDEEF, "DEC RAX");
}
#[test]
fn test_dec_rax_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc8, 0xf4];
emu.regs_mut().rax = 0x0000000000000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xFFFFFFFFFFFFFFFF, "DEC RAX: 0 - 1 = max");
assert!(emu.flags().f_sf, "SF should be set");
}
#[test]
fn test_dec_rax_signed_underflow() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0xc8, 0xf4];
emu.regs_mut().rax = 0x8000000000000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x7FFFFFFFFFFFFFFF);
assert!(emu.flags().f_of, "OF should be set (signed underflow)");
assert!(!emu.flags().f_sf, "SF should be clear");
}
#[test]
fn test_dec_rax_memory() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xff, 0x0b, 0xf4];
emu.regs_mut().rbx = DATA_ADDR;
emu.load_code_bytes(&code);
emu.maps.write_qword(DATA_ADDR, 0xFEDCBA9876543210);
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(DATA_ADDR).unwrap(), 0xFEDCBA987654320F);
}
#[test]
fn test_inc_ecx() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc1, 0xf4]; emu.regs_mut().rcx = 99;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx, 100, "INC ECX: 99 + 1 = 100");
}
#[test]
fn test_dec_ecx() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xff, 0xc9, 0xf4]; emu.regs_mut().rcx = 100;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx, 99, "DEC ECX: 100 - 1 = 99");
}
#[test]
fn test_inc_cl() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc1, 0xf4]; emu.regs_mut().rcx = 255;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx & 0xFF, 0, "INC CL: 255 + 1 = 0 (wraps)");
}
#[test]
fn test_dec_cl() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc9, 0xf4]; emu.regs_mut().rcx = 0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rcx & 0xFF, 0xFF, "DEC CL: 0 - 1 = 0xFF");
}
#[test]
fn test_inc_parity_flag() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0x02;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x03);
assert!(emu.flags().f_pf, "PF should be set (even parity)");
}
#[test]
fn test_inc_auxiliary_flag() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0x0F;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x10);
assert!(emu.flags().f_af, "AF should be set (carry from bit 3)");
}
#[test]
fn test_inc_no_auxiliary_flag() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0x0E;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x0F);
assert!(!emu.flags().f_af, "AF should be clear");
}
#[test]
fn test_dec_parity_flag() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x04;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x03);
assert!(emu.flags().f_pf, "PF should be set (even parity)");
}
#[test]
fn test_dec_auxiliary_flag() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x0F);
assert!(emu.flags().f_af, "AF should be set (borrow from bit 4)");
}
#[test]
fn test_inc_cf_independence() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFF;
emu.flags_mut().load(0x2); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert!(!emu.flags().f_cf, "CF should remain clear");
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0xFF;
emu.flags_mut().load(0x2 | flags::F_CF); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should remain set");
}
#[test]
fn test_dec_cf_independence() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x00;
emu.flags_mut().load(0x2); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert!(!emu.flags().f_cf, "CF should remain clear");
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0x00;
emu.flags_mut().load(0x2 | flags::F_CF); emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should remain set");
}
#[test]
fn test_inc_r8d_extended() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xff, 0xc0, 0xf4]; emu.regs_mut().r8 = 100;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r8, 101, "INC R8D: 100 + 1 = 101");
}
#[test]
fn test_dec_r8d_extended() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xff, 0xc8, 0xf4]; emu.regs_mut().r8 = 100;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r8, 99, "DEC R8D: 100 - 1 = 99");
}
#[test]
fn test_inc_r15_extended() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x49, 0xff, 0xc7, 0xf4]; emu.regs_mut().r15 = 0xFFFFFFFFFFFFFFFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r15, 0, "INC R15: max + 1 = 0");
assert!(emu.flags().f_zf, "ZF should be set");
}
#[test]
fn test_dec_r15_extended() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x49, 0xff, 0xcf, 0xf4]; emu.regs_mut().r15 = 0x0000000000000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r15, 0xFFFFFFFFFFFFFFFF, "DEC R15: 0 - 1 = max");
assert!(emu.flags().f_sf, "SF should be set");
}
#[test]
fn test_inc_r8l_byte() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xfe, 0xc0, 0xf4]; emu.regs_mut().r8 = 0xFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r8 & 0xFF, 0, "INC R8L: 0xFF + 1 = 0x00");
}
#[test]
fn test_dec_r8l_byte() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xfe, 0xc8, 0xf4]; emu.regs_mut().r8 = 0x00;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().r8 & 0xFF, 0xFF, "DEC R8L: 0x00 - 1 = 0xFF");
}
#[test]
fn test_inc_as_loop_counter() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xf4, ];
emu.regs_mut().rax = 0;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 3, "Three INC operations: 0 + 1 + 1 + 1 = 3");
}
#[test]
fn test_dec_as_loop_counter() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xff, 0xc8, 0xff, 0xc8, 0xff, 0xc8, 0xf4, ];
emu.regs_mut().rax = 5;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 2, "Three DEC operations: 5 - 1 - 1 - 1 = 2");
}
#[test]
fn test_inc_preserves_high_bytes() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc0, 0xf4];
emu.regs_mut().rax = 0xDEADBEEF_12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x79);
assert_eq!(
emu.regs().rax & !0xFF,
0xDEADBEEF_12345600,
"High bytes should be preserved"
);
}
#[test]
fn test_dec_preserves_high_bytes() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xfe, 0xc8, 0xf4];
emu.regs_mut().rax = 0xDEADBEEF_12345678;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0x77);
assert_eq!(
emu.regs().rax & !0xFF,
0xDEADBEEF_12345600,
"High bytes should be preserved"
);
}