use crate::*;
use std::convert::TryInto;
const DATA_ADDR: u64 = 0x7000;
#[test]
fn test_pushfq_basic() {
let code = [
0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x0FF8, "RSP decremented by 8");
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags, 0, "Flags should be pushed");
}
#[test]
fn test_pushfq_with_carry_set() {
let code = [
0xf9, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x01, 0, "CF should be set in pushed flags");
}
#[test]
fn test_pushfq_with_zero_set() {
let code = [
0x48, 0x31, 0xc0, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x40, 0, "ZF should be set in pushed flags");
}
#[test]
fn test_pushfq_with_sign_set() {
let code = [
0x48, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x80, 0, "SF should be set in pushed flags");
}
#[test]
fn test_pushfq_multiple_flags() {
let code = [
0x48, 0x31, 0xc0, 0xf9, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x01, 0, "CF should be set");
assert_ne!(pushed_flags & 0x40, 0, "ZF should be set");
}
#[test]
fn test_pushfq_preserves_registers() {
let code = [
0x48, 0xc7, 0xc0, 0x42, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc3, 0x99, 0x00, 0x00, 0x00, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x42, "RAX unchanged");
assert_eq!(emu.regs().rbx, 0x99, "RBX unchanged");
}
#[test]
fn test_pushfq_multiple_times() {
let code = [
0xf9, 0x48, 0x9c, 0xf8, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000 - 16, "RSP decremented twice");
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let first_flags = u64::from_le_bytes(stack_val);
stack_val = emu.maps.read_bytes(0x0FF0, stack_val.len()).try_into().unwrap();
let second_flags = u64::from_le_bytes(stack_val);
assert_ne!(first_flags & 0x01, 0, "First PUSHFQ has CF set");
assert_eq!(second_flags & 0x01, 0, "Second PUSHFQ has CF clear");
}
#[test]
fn test_popfq_basic() {
let code = [
0x48, 0x9c, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000, "RSP restored");
}
#[test]
fn test_popfq_restore_carry() {
let code = [
0xf9, 0x48, 0x9c, 0xf8, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored");
}
#[test]
fn test_popfq_restore_zero() {
let code = [
0x48, 0x31, 0xc0, 0x48, 0x9c, 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_zf, "ZF should be restored");
}
#[test]
fn test_popfq_restore_sign() {
let code = [
0x48, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x48, 0x9c, 0x48, 0x31, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_sf, "SF should be restored");
}
#[test]
fn test_popfq_restore_all_flags() {
let code = [
0x48, 0x31, 0xc0, 0xf9, 0x48, 0x9c, 0xf8, 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored");
assert!(emu.flags().f_zf, "ZF should be restored");
}
#[test]
fn test_popfq_preserves_registers() {
let code = [
0x48, 0xc7, 0xc0, 0x42, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc3, 0x99, 0x00, 0x00, 0x00, 0x48, 0x9c, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x42, "RAX unchanged");
assert_eq!(emu.regs().rbx, 0x99, "RBX unchanged");
}
#[test]
fn test_pushfq_popfq_roundtrip() {
let code = [
0xf9, 0x48, 0x9c, 0xf8, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored by POPFQ");
assert_eq!(emu.regs().rsp, 0x1000, "RSP should be balanced");
}
#[test]
fn test_pushfq_popfq_nested() {
let code = [
0xf9, 0x48, 0x9c, 0xf8, 0x48, 0x9c, 0x48, 0x9d, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored from first PUSHFQ");
assert_eq!(emu.regs().rsp, 0x1000, "Stack should be balanced");
}
#[test]
fn test_pushfq_popfq_with_arithmetic() {
let code = [
0x48, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x48, 0x83, 0xc0, 0x01, 0x48, 0x9c, 0x48, 0xc7, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x01, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_zf, "ZF should be restored");
assert!(emu.flags().f_cf, "CF should be restored");
}
#[test]
fn test_pushfq_modify_on_stack() {
let code = [
0x48, 0x9c, 0x48, 0x8b, 0x04, 0x24, 0x48, 0x83, 0xc8, 0x01, 0x48, 0x89, 0x04, 0x24, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be set from modified stack value");
}
#[test]
fn test_multiple_pushfq_popfq() {
let code = [
0xf9, 0x48, 0x9c, 0x48, 0x9c, 0x48, 0x9c, 0x48, 0x9d, 0x48, 0x9d, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000, "Stack should be balanced");
assert!(emu.flags().f_cf, "CF should still be set");
}
#[test]
fn test_pushf_16bit() {
let code = [
0x66, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x0FFE, "RSP decremented by 2");
}
#[test]
fn test_popf_16bit() {
let code = [
0x66, 0x9c, 0x66, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000, "RSP should be balanced");
}
#[test]
fn test_pushfq_at_stack_boundary() {
let code = [
0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x08-(0x08 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x08; emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x00, "RSP decremented");
}
#[test]
fn test_popfq_from_prepared_stack() {
let code = [
0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x3000-(0x3000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x3000;
let flags_with_cf = 0x0001u64;
let flags_bytes = flags_with_cf.to_le_bytes();
emu.maps.write_bytes_slice(0x3000, &flags_bytes);
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be set from stack");
}
#[test]
fn test_pushfq_popfq_preserves_reserved_bits() {
let code = [
0x48, 0x9c, 0x48, 0x9d, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(emu.regs().rsp, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x02, 0, "Reserved bit 1 should be set");
}
#[test]
fn test_pushfq_with_overflow() {
let code = [
0xb8, 0xff, 0xff, 0xff, 0x7f, 0x83, 0xc0, 0x01, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x800, 0, "OF should be set in pushed flags");
}
#[test]
fn test_popfq_restore_overflow() {
let code = [
0xb8, 0xff, 0xff, 0xff, 0x7f, 0x83, 0xc0, 0x01, 0x48, 0x9c, 0x48, 0x31, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_of, "OF should be restored");
}
#[test]
fn test_pushfq_with_direction_flag() {
let code = [
0xfd, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x400, 0, "DF should be set in pushed flags");
}
#[test]
fn test_popfq_restore_direction_flag() {
let code = [
0xfd, 0x48, 0x9c, 0xfc, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_df, "DF should be restored");
}
#[test]
fn test_pushfq_popfq_with_all_status_flags() {
let code = [
0xb8, 0xff, 0xff, 0xff, 0x7f, 0x83, 0xc0, 0x01, 0xf9, 0xfd, 0x48, 0x9c, 0xf8, 0xfc, 0x48, 0x31, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored");
assert!(emu.flags().f_df, "DF should be restored");
assert!(emu.flags().f_of, "OF should be restored");
}
#[test]
fn test_pushfq_after_comparison() {
let code = [
0x48, 0xc7, 0xc0, 0x0a, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc3, 0x05, 0x00, 0x00, 0x00, 0x48, 0x39, 0xd8, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_eq!(pushed_flags & 0x01, 0, "CF should be clear (10 >= 5)");
assert_eq!(pushed_flags & 0x40, 0, "ZF should be clear (10 != 5)");
assert_eq!(pushed_flags & 0x80, 0, "SF should be clear (positive result)");
}
#[test]
fn test_popfq_after_comparison() {
let code = [
0x48, 0xc7, 0xc0, 0x05, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc3, 0x0a, 0x00, 0x00, 0x00, 0x48, 0x39, 0xd8, 0x48, 0x9c, 0x48, 0x39, 0xc3, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be restored from first comparison");
}
#[test]
fn test_pushfq_popfq_in_loop_simulation() {
let code = [
0xf9, 0x48, 0x9c, 0xf8, 0x48, 0x31, 0xc0, 0x48, 0x9d, 0x48, 0x9c, 0xf8, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_cf, "CF should be preserved through multiple save/restore");
assert_eq!(emu.regs().rsp, 0x1000, "Stack should be balanced");
}
#[test]
fn test_pushfq_with_parity_flag() {
let code = [
0x48, 0xc7, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x04, 0, "PF should be set in pushed flags");
}
#[test]
fn test_popfq_restore_parity() {
let code = [
0x48, 0xc7, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x48, 0x9c, 0x48, 0xc7, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_pf, "PF should be restored");
}
#[test]
fn test_pushfq_with_auxiliary_carry() {
let code = [
0x48, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x01, 0x48, 0x9c, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let mut stack_val = [0u8; 8];
stack_val = emu.maps.read_bytes(0x0FF8, stack_val.len()).try_into().unwrap();
let pushed_flags = u64::from_le_bytes(stack_val);
assert_ne!(pushed_flags & 0x10, 0, "AF should be set in pushed flags");
}
#[test]
fn test_popfq_restore_auxiliary_carry() {
let code = [
0x48, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x01, 0x48, 0x9c, 0x48, 0x31, 0xc0, 0x48, 0x9d, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert!(emu.flags().f_af, "AF should be restored");
}