FPU: Implement zero divide fault
This commit is contained in:
parent
0269e9cecf
commit
158bb75fec
|
@ -3,6 +3,7 @@ use std::mem::transmute;
|
|||
use cpu2::cpu::*;
|
||||
use cpu2::global_pointers::*;
|
||||
use paging::OrPageFault;
|
||||
use std::f64;
|
||||
|
||||
pub fn round(x: f64) -> f64 { x.round() }
|
||||
pub fn floor(x: f64) -> f64 { x.floor() }
|
||||
|
@ -23,6 +24,7 @@ const FPU_C3: i32 = 0x4000;
|
|||
const FPU_RESULT_FLAGS: i32 = FPU_C0 | FPU_C1 | FPU_C2 | FPU_C3;
|
||||
const INDEFINITE_NAN: f64 = ::std::f64::NAN;
|
||||
const FPU_EX_I: i32 = 1 << 0;
|
||||
const FPU_EX_Z: i32 = 1 << 2;
|
||||
const FPU_EX_SF: i32 = 1 << 6;
|
||||
const TWO_POW_63: f64 = 0x8000000000000000u64 as f64;
|
||||
|
||||
|
@ -89,6 +91,12 @@ pub unsafe fn fpu_stack_fault() {
|
|||
*fpu_status_word |= FPU_EX_SF | FPU_EX_I;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn fpu_zero_fault() {
|
||||
// TODO: Interrupt
|
||||
*fpu_status_word |= FPU_EX_Z;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn fpu_sti_empty(mut i: i32) -> bool {
|
||||
dbg_assert!(i >= 0 && i < 8);
|
||||
|
@ -305,11 +313,17 @@ pub unsafe fn fpu_fcomp(val: f64) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn fpu_fdiv(target_index: i32, val: f64) {
|
||||
let st0: f64 = fpu_get_st0();
|
||||
if val == 0.0 {
|
||||
fpu_zero_fault();
|
||||
}
|
||||
fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, st0 / val);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn fpu_fdivr(target_index: i32, val: f64) {
|
||||
let st0: f64 = fpu_get_st0();
|
||||
if st0 == 0.0 {
|
||||
fpu_zero_fault();
|
||||
}
|
||||
fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val / st0);
|
||||
}
|
||||
#[no_mangle]
|
||||
|
@ -762,15 +776,37 @@ pub unsafe fn fpu_fxch(i: i32) {
|
|||
fpu_write_st(*fpu_stack_ptr as i32 + i & 7, fpu_get_st0());
|
||||
fpu_write_st(*fpu_stack_ptr as i32, sti);
|
||||
}
|
||||
pub unsafe fn fpu_fyl2x() {
|
||||
let st0 = fpu_get_st0();
|
||||
if st0 < 0.0 {
|
||||
fpu_invalid_arithmetic();
|
||||
}
|
||||
else if st0 == 0.0 {
|
||||
fpu_zero_fault();
|
||||
}
|
||||
fpu_write_st(
|
||||
*fpu_stack_ptr as i32 + 1 & 7,
|
||||
fpu_get_sti(1) * st0.ln() / M_LN2,
|
||||
);
|
||||
fpu_pop();
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn fpu_fxtract() {
|
||||
let mut f = FloatParts::of_f64(fpu_get_st0());
|
||||
fpu_write_st(
|
||||
*fpu_stack_ptr as i32,
|
||||
f.exponent as f64 - F64_EXPONENT_BIAS as f64,
|
||||
);
|
||||
f.exponent = 0x3FF;
|
||||
fpu_push(f.to_f64());
|
||||
let st0 = fpu_get_st0();
|
||||
if st0 == 0.0 {
|
||||
fpu_zero_fault();
|
||||
fpu_write_st(*fpu_stack_ptr as i32, f64::NEG_INFINITY);
|
||||
fpu_push(st0);
|
||||
}
|
||||
else {
|
||||
let mut f = FloatParts::of_f64(st0);
|
||||
fpu_write_st(
|
||||
*fpu_stack_ptr as i32,
|
||||
f.exponent as f64 - F64_EXPONENT_BIAS as f64,
|
||||
);
|
||||
f.exponent = 0x3FF;
|
||||
fpu_push(f.to_f64());
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn fwait() {
|
||||
|
|
|
@ -3698,14 +3698,7 @@ pub unsafe fn instr_D9_6_reg(r: i32) {
|
|||
},
|
||||
1 => {
|
||||
// fyl2x
|
||||
if st0 < 0.0 {
|
||||
fpu_invalid_arithmetic();
|
||||
}
|
||||
fpu_write_st(
|
||||
*fpu_stack_ptr as i32 + 1 & 7,
|
||||
fpu_get_sti(1) * st0.ln() / M_LN2,
|
||||
);
|
||||
fpu_pop();
|
||||
fpu_fyl2x();
|
||||
},
|
||||
2 => {
|
||||
// fptan
|
||||
|
|
14
tests/nasm/fdiv-zero.asm
Normal file
14
tests/nasm/fdiv-zero.asm
Normal file
|
@ -0,0 +1,14 @@
|
|||
global _start
|
||||
|
||||
section .data
|
||||
align 16
|
||||
|
||||
%include "header.inc"
|
||||
|
||||
push 1234
|
||||
fild dword [esp]
|
||||
push 0
|
||||
fild dword [esp]
|
||||
fdiv
|
||||
|
||||
%include "footer.inc"
|
12
tests/nasm/fxtract-zero.asm
Normal file
12
tests/nasm/fxtract-zero.asm
Normal file
|
@ -0,0 +1,12 @@
|
|||
global _start
|
||||
|
||||
section .data
|
||||
align 16
|
||||
|
||||
%include "header.inc"
|
||||
|
||||
push 0
|
||||
fild dword [esp]
|
||||
fxtract
|
||||
|
||||
%include "footer.inc"
|
14
tests/nasm/fyl2x-zero.asm
Normal file
14
tests/nasm/fyl2x-zero.asm
Normal file
|
@ -0,0 +1,14 @@
|
|||
global _start
|
||||
|
||||
section .data
|
||||
align 16
|
||||
|
||||
%include "header.inc"
|
||||
|
||||
push 1234
|
||||
fild dword [esp]
|
||||
push 0
|
||||
fild dword [esp]
|
||||
fyl2x
|
||||
|
||||
%include "footer.inc"
|
Loading…
Reference in a new issue