use crate::*;
#[test]
fn test_idiv_al_positive() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 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) = 0");
}
#[test]
fn test_idiv_al_negative_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-100i32) as u64 & 0xFF; emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = (emu.regs().rax & 0xFF) as i8;
assert_eq!(quotient, -10, "-100 / 10 = -10");
}
#[test]
fn test_idiv_al_negative_divisor() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 0xf4,
];
emu.regs_mut().rax = 100;
emu.regs_mut().rbx = (-10i32) as u64 & 0xFF; emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = (emu.regs().rax & 0xFF) as i8;
assert_eq!(quotient, -10, "100 / -10 = -10");
}
#[test]
fn test_idiv_al_both_negative() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-100i32) as u64 & 0xFF;
emu.regs_mut().rbx = (-10i32) as u64 & 0xFF;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = (emu.regs().rax & 0xFF) as i8;
assert_eq!(quotient, 10, "-100 / -10 = 10");
}
#[test]
fn test_idiv_al_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 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)");
assert_eq!((emu.regs().rax >> 8) & 0xFF, 2, "AH (remainder)");
}
#[test]
fn test_idiv_al_negative_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-100i32) as u64 & 0xFF;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = (emu.regs().rax & 0xFF) as i8;
let remainder = ((emu.regs().rax >> 8) & 0xFF) as i8;
assert_eq!(quotient, -14, "Quotient");
assert_eq!(remainder, -2, "Remainder");
}
#[test]
fn test_idiv_ax_positive() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x99, 0x66, 0xf7, 0xfb, 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)");
assert_eq!(emu.regs().rdx & 0xFFFF, 0, "DX (remainder)");
}
#[test]
fn test_idiv_ax_negative_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x99, 0x66, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000i32) as u64 & 0xFFFF;
emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = (emu.regs().rax & 0xFFFF) as i16;
assert_eq!(quotient, -100, "-1000 / 10 = -100");
}
#[test]
fn test_idiv_ax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x99, 0x66, 0xf7, 0xfb, 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_idiv_eax_positive() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 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_idiv_eax_negative_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000i32) as u64;
emu.regs_mut().rbx = 1000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i32;
assert_eq!(quotient, -1000, "-1000000 / 1000 = -1000");
}
#[test]
fn test_idiv_eax_negative_divisor() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = 1000000;
emu.regs_mut().rbx = (-1000i32) as u64;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i32;
assert_eq!(quotient, -1000, "1000000 / -1000 = -1000");
}
#[test]
fn test_idiv_eax_both_negative() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000i32) as u64;
emu.regs_mut().rbx = (-1000i32) as u64;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i32;
assert_eq!(quotient, 1000, "-1000000 / -1000 = 1000");
}
#[test]
fn test_idiv_eax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 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_idiv_eax_negative_dividend_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000i32) as u64;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i32;
let remainder = emu.regs().rdx as i32;
assert_eq!(quotient, -142857, "EAX (quotient)");
assert_eq!(remainder, -1, "EDX (remainder)");
}
#[test]
fn test_idiv_rax_positive() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 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_idiv_rax_negative_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000000000i64) as u64;
emu.regs_mut().rbx = 1000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i64;
assert_eq!(quotient, -1000000, "-1000000000000 / 1000000 = -1000000");
}
#[test]
fn test_idiv_rax_negative_divisor() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = 1000000000000;
emu.regs_mut().rbx = (-1000000i64) as u64;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i64;
assert_eq!(quotient, -1000000, "1000000000000 / -1000000 = -1000000");
}
#[test]
fn test_idiv_rax_both_negative() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000000000i64) as u64;
emu.regs_mut().rbx = (-1000000i64) as u64;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i64;
assert_eq!(quotient, 1000000, "-1000000000000 / -1000000 = 1000000");
}
#[test]
fn test_idiv_rax_with_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 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_idiv_rax_negative_dividend_remainder() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-1000000000000i64) as u64;
emu.regs_mut().rbx = 7;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i64;
let remainder = emu.regs().rdx as i64;
assert_eq!(quotient, -142857142857, "RAX (quotient)");
assert_eq!(remainder, -1, "RDX (remainder)");
}
#[test]
fn test_idiv_cl_register() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0xf9, 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_idiv_ecx_32bit() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xf9, 0xf4,
];
emu.regs_mut().rax = 1000000;
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_idiv_r8b() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0x41, 0xf6, 0xf8, 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)");
}
#[test]
fn test_idiv_r10d() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0x41, 0xf7, 0xfa, 0xf4,
];
emu.regs_mut().rax = 1000000;
emu.regs_mut().r10 = 1000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient)");
}
#[test]
fn test_idiv_r15() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x49, 0xf7, 0xff, 0xf4,
];
emu.regs_mut().rax = 1000000000000;
emu.regs_mut().r15 = 1000000;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000000, "RAX (quotient)");
}
#[test]
fn test_idiv_byte_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x66, 0x98, 0xf6, 0x3d, 0xf8, 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)");
}
#[test]
fn test_idiv_dword_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0x3d, 0xf9, 0x0f, 0x00,
0x00, 0xf4,
];
emu.load_code_bytes(&code);
emu.maps.write_dword(DATA_ADDR, 1000);
emu.regs_mut().rax = 1000000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000, "EAX (quotient)");
assert_eq!(emu.regs().rdx, 0, "EDX (remainder)");
}
#[test]
fn test_idiv_qword_ptr_mem() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x48, 0x99, 0x48, 0xf7, 0x3d, 0xf7, 0x0f, 0x00,
0x00, 0xf4,
];
emu.load_code_bytes(&code);
emu.maps.write_qword(DATA_ADDR, 1000000);
emu.regs_mut().rax = 1000000000000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 1000000, "RAX (quotient)");
}
#[test]
fn test_idiv_small_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 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, 0, "Quotient = 0");
assert_eq!(emu.regs().rdx, 5, "Remainder = 5");
}
#[test]
fn test_idiv_negative_small_dividend() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = (-5i32) as u64;
emu.regs_mut().rbx = 10;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
let quotient = emu.regs().rax as i32;
let remainder = emu.regs().rdx as i32;
assert_eq!(quotient, 0, "Quotient = 0");
assert_eq!(remainder, -5, "Remainder = -5 (sign of dividend)");
}
#[test]
fn test_idiv_power_of_two() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = 1024;
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_idiv_max_positive() {
let DATA_ADDR = 0x7000;
let mut emu = emu64();
let code = [
0x99, 0xf7, 0xfb, 0xf4,
];
emu.regs_mut().rax = 0x7FFFFFFF;
emu.regs_mut().rbx = 1;
emu.load_code_bytes(&code);
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x7FFFFFFF, "Quotient = max i32");
assert_eq!(emu.regs().rdx, 0, "Remainder = 0");
}