use crate::*;
#[test]
fn test_div_al_simple() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xf6, 0xf3, 0xf4, ];
emu.regs_mut().rax = 100; emu.regs_mut().rbx = 10; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 10, "AL (quotient) = 100 / 10 = 10");
assert_eq!(
(emu.regs().rax >> 8) & 0xFF,
0,
"AH (remainder) = 100 % 10 = 0"
);
}
#[test]
fn test_div_al_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf3, 0xf4]; emu.regs_mut().rax = 100;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 14, "AL (quotient) = 100 / 7 = 14");
assert_eq!(
(emu.regs().rax >> 8) & 0xFF,
2,
"AH (remainder) = 100 % 7 = 2"
);
}
#[test]
fn test_div_al_max_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf3, 0xf4]; emu.regs_mut().rax = 255;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 255, "AL = 255 / 1 = 255");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 0, "AH = 0");
}
#[test]
fn test_div_al_large_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf3, 0xf4]; emu.regs_mut().rax = 300;
emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 30, "AL (quotient) = 300 / 10 = 30");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 0, "AH (remainder) = 0");
}
#[test]
fn test_div_al_one() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf3, 0xf4]; emu.regs_mut().rax = 5;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 5, "5 / 1 = 5");
}
#[test]
fn test_div_ax_simple() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0xf7, 0xf3, 0xf4,
];
emu.regs_mut().rax = 1000;
emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(
emu.regs().rax & 0xFFFF,
100,
"AX (quotient) = 1000 / 10 = 100"
);
assert_eq!(emu.regs().rdx & 0xFFFF, 0, "DX (remainder) = 0");
}
#[test]
fn test_div_ax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 1000;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 142, "AX (quotient)");
assert_eq!(emu.regs().rdx & 0xFFFF, 6, "DX (remainder)");
}
#[test]
fn test_div_ax_dx_nonzero() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0x1000; emu.regs_mut().rdx = 0x0001; emu.regs_mut().rbx = 100;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 696, "AX (quotient)");
assert_eq!(emu.regs().rdx & 0xFFFF, 32, "DX (remainder)");
}
#[test]
fn test_div_ax_max_quotient() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0xFFFF;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 0xFFFF, "AX = 65535");
assert_eq!(emu.regs().rdx & 0xFFFF, 0, "DX = 0");
}
#[test]
fn test_div_eax_simple() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xf7, 0xf3, 0xf4,
];
emu.regs_mut().rax = 1000000;
emu.regs_mut().rbx = 1000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "EDX (remainder)");
}
#[test]
fn test_div_eax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 1000000;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 142857, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 1, "EDX (remainder)");
}
#[test]
fn test_div_eax_edx_nonzero() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0x00000000;
emu.regs_mut().rdx = 0x00000001;
emu.regs_mut().rbx = 100;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 42949672, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 96, "EDX (remainder)");
}
#[test]
fn test_div_eax_max_quotient() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0xFFFFFFFF;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xFFFFFFFF, "EAX = max 32-bit");
assert_eq!(emu.regs().rdx, 0, "EDX = 0");
}
#[test]
fn test_div_eax_one() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 1234567;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1234567, "quotient");
assert_eq!(emu.regs().rdx, 0, "remainder");
}
#[test]
fn test_div_rax_simple() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0xf7, 0xf3, 0xf4,
];
emu.regs_mut().rax = 1000000000000;
emu.regs_mut().rbx = 1000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000000, "RAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "RDX (remainder)");
}
#[test]
fn test_div_rax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 1000000000000;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 142857142857, "RAX (quotient)");
assert_eq!(emu.regs().rdx, 1, "RDX (remainder)");
}
#[test]
fn test_div_rax_rdx_nonzero() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0x0000000000000000;
emu.regs_mut().rdx = 0x0000000000000001; emu.regs_mut().rbx = 0x100000001; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xFFFFFFFF, "RAX (quotient)");
assert_eq!(emu.regs().rdx, 1, "RDX (remainder)");
}
#[test]
fn test_div_rax_max_quotient() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0xFFFFFFFFFFFFFFFF;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xFFFFFFFFFFFFFFFF, "RAX = max 64-bit");
assert_eq!(emu.regs().rdx, 0, "RDX = 0");
}
#[test]
fn test_div_rax_one() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x48, 0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 123456789123456789;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 123456789123456789, "quotient");
assert_eq!(emu.regs().rdx, 0, "remainder");
}
#[test]
fn test_div_cl_register() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf1, 0xf4];
emu.regs_mut().rax = 100;
emu.regs_mut().rcx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 10, "AL (quotient)");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 0, "AH (remainder)");
}
#[test]
fn test_div_cx_16bit() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x66, 0xf7, 0xf1, 0xf4]; emu.regs_mut().rax = 10000; emu.regs_mut().rdx = 0; emu.regs_mut().rcx = 100; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFF, 100, "AX (quotient)");
assert_eq!(emu.regs().rdx & 0xFFFF, 0, "DX (remainder)");
}
#[test]
fn test_div_ecx_32bit() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf1, 0xf4]; emu.regs_mut().rax = 1000000;
emu.regs_mut().rdx = 0;
emu.regs_mut().rcx = 1000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "EDX (remainder)");
}
#[test]
fn test_div_r8b() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xf6, 0xf0, 0xf4]; emu.regs_mut().rax = 100;
emu.regs_mut().r8 = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 10, "AL (quotient)");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 0, "AH (remainder)");
}
#[test]
fn test_div_r10d() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x41, 0xf7, 0xf2, 0xf4]; emu.regs_mut().rax = 1000000;
emu.regs_mut().rdx = 0;
emu.regs_mut().r10 = 1000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "EDX (remainder)");
}
#[test]
fn test_div_r15() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0x49, 0xf7, 0xf7, 0xf4]; emu.regs_mut().rax = 1000000000000;
emu.regs_mut().rdx = 0;
emu.regs_mut().r15 = 1000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000000, "RAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "RDX (remainder)");
}
#[test]
fn test_div_byte_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xf6, 0x35, 0xfa, 0x0f, 0x00, 0x00, 0xf4,
];
emu.load_code_bytes(&code);
emu.maps.write_byte(DATA_ADDR, 10);
emu.regs_mut().rax = 100;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 10, "AL (quotient) = 100 / 10");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 0, "AH (remainder)");
}
#[test]
fn test_div_dword_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0xf7, 0x35, 0xfa, 0x0f, 0x00, 0x00, 0xf4,
];
emu.load_code_bytes(&code);
emu.maps.write_dword(DATA_ADDR, 1000);
emu.regs_mut().rax = 1000000;
emu.regs_mut().rdx = 0;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient) = 1000000 / 1000");
assert_eq!(emu.regs().rdx, 0, "EDX (remainder)");
}
#[test]
fn test_div_qword_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0xf7, 0x35, 0xf9, 0x0f, 0x00, 0x00, 0xf4,
];
emu.load_code_bytes(&code);
emu.maps.write_qword(DATA_ADDR, 1000000);
emu.regs_mut().rax = 1000000000000;
emu.regs_mut().rdx = 0;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000000, "RAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "RDX (remainder)");
}
#[test]
fn test_div_small_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf6, 0xf3, 0xf4]; emu.regs_mut().rax = 5;
emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFF, 0, "AL (quotient) = 0");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 5, "AH (remainder) = 5");
}
#[test]
fn test_div_power_of_two() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 1024;
emu.regs_mut().rdx = 0;
emu.regs_mut().rbx = 256;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 4, "quotient");
assert_eq!(emu.regs().rdx, 0, "remainder");
}
#[test]
fn test_div_result_in_upper() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [0xf7, 0xf3, 0xf4]; emu.regs_mut().rax = 0x00000000;
emu.regs_mut().rdx = 0x00000002; emu.regs_mut().rbx = 0x80000000; emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax & 0xFFFFFFFF, 4, "EAX (quotient)");
assert_eq!(emu.regs().rdx & 0xFFFFFFFF, 0, "EDX (remainder)");
}