From c75c1e780c7ef0ce22f63db145bf2e5278274075 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Tue, 10 Oct 2023 20:03:13 -0600 Subject: [PATCH] fix flush mode --- src/device.rs | 1 + src/device/cop1.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/device.rs b/src/device.rs index 6152be9..18e4a4d 100644 --- a/src/device.rs +++ b/src/device.rs @@ -107,6 +107,7 @@ impl Device { cop1: cop1::Cop1 { fcr0: 0, fcr31: 0, + flush_mode: 0, fgr32: [[0; 4]; 32], fgr64: [[0; 8]; 32], instrs: [cop1::reserved; 32], diff --git a/src/device/cop1.rs b/src/device/cop1.rs index a071ecd..c885ce3 100644 --- a/src/device/cop1.rs +++ b/src/device/cop1.rs @@ -17,6 +17,7 @@ use crate::device; //pub const FCR31_CAUSE_INVALID_BIT: u32 = 1 << 16; pub const FCR31_CAUSE_UNIMP_BIT: u32 = 1 << 17; pub const FCR31_CMP_BIT: u32 = 1 << 23; +pub const FCR31_FS_BIT: u32 = 1 << 24; pub const FCR31_CAUSE_MASK: u32 = 0b00000000000000111111000000000000; pub const FCR31_ENABLE_MASK: u32 = 0b00000000000000000000111110000000; @@ -25,6 +26,7 @@ pub const FCR31_WRITE_MASK: u32 = 0b00000001100000111111111111111111; pub struct Cop1 { pub fcr0: u32, pub fcr31: u32, + pub flush_mode: u32, pub fgr32: [[u8; 4]; 32], pub fgr64: [[u8; 8]; 32], pub instrs: [fn(&mut device::Device, u32); 32], @@ -364,6 +366,24 @@ pub fn set_control_registers_fpu(device: &mut device::Device, index: u32, data: { device::exceptions::floating_point_exception(device) } + + unsafe { + let flush_mode; + if (device.cpu.cop1.fcr31 & 2) != 0 { + if (device.cpu.cop1.fcr31 & FCR31_FS_BIT) != 0 { + flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_OFF + } else { + flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_ON; + } + } else { + flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_ON; + } + if flush_mode != device.cpu.cop1.flush_mode { + #[allow(deprecated)] + std::arch::x86_64::_MM_SET_FLUSH_ZERO_MODE(flush_mode); + device.cpu.cop1.flush_mode = flush_mode; + } + } } _ => { panic!("unknown FCR register")