https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92c798c657d5f0a315624b864e3d0b0c03715f6d

commit 92c798c657d5f0a315624b864e3d0b0c03715f6d
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Wed Jul 13 20:26:42 2022 +0200
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Mon Aug 22 11:22:08 2022 +0200

    [NTOSKRNL] Implement KiXmmExceptionHandler
---
 ntoskrnl/ke/amd64/except.c | 48 +++++++++++++++++++++++++++++++++++++++++++---
 ntoskrnl/ke/amd64/trap.S   |  4 +++-
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/ntoskrnl/ke/amd64/except.c b/ntoskrnl/ke/amd64/except.c
index de8e2b01697..8410fa4acc6 100644
--- a/ntoskrnl/ke/amd64/except.c
+++ b/ntoskrnl/ke/amd64/except.c
@@ -672,7 +672,49 @@ NTAPI
 KiXmmExceptionHandler(
     IN PKTRAP_FRAME TrapFrame)
 {
-    UNIMPLEMENTED;
-    KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
-    return -1;
+    ULONG ExceptionCode;
+
+    if ((TrapFrame->MxCsr & _MM_EXCEPT_INVALID) &&
+        !(TrapFrame->MxCsr & _MM_MASK_INVALID))
+    {
+        /* Invalid operation */
+        ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
+    }
+    else if ((TrapFrame->MxCsr & _MM_EXCEPT_DENORM) &&
+             !(TrapFrame->MxCsr & _MM_MASK_DENORM))
+    {
+        /* Denormalized operand. Yes, this is what Windows returns. */
+        ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
+    }
+    else if ((TrapFrame->MxCsr & _MM_EXCEPT_DIV_ZERO) &&
+             !(TrapFrame->MxCsr & _MM_MASK_DIV_ZERO))
+    {
+        /* Divide by zero */
+        ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
+    }
+    else if ((TrapFrame->MxCsr & _MM_EXCEPT_OVERFLOW) &&
+             !(TrapFrame->MxCsr & _MM_MASK_OVERFLOW))
+    {
+        /* Overflow */
+        ExceptionCode = STATUS_FLOAT_OVERFLOW;
+    }
+    else if ((TrapFrame->MxCsr & _MM_EXCEPT_UNDERFLOW) &&
+             !(TrapFrame->MxCsr & _MM_MASK_UNDERFLOW))
+    {
+        /* Underflow */
+        ExceptionCode = STATUS_FLOAT_UNDERFLOW;
+    }
+    else if ((TrapFrame->MxCsr & _MM_EXCEPT_INEXACT) &&
+             !(TrapFrame->MxCsr & _MM_MASK_INEXACT))
+    {
+        /* Precision */
+        ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
+    }
+    else
+    {
+        /* Should not happen */
+        ASSERT(FALSE);
+    }
+    
+    return ExceptionCode;
 }
diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S
index 73470363a23..9d694518d0f 100644
--- a/ntoskrnl/ke/amd64/trap.S
+++ b/ntoskrnl/ke/amd64/trap.S
@@ -543,7 +543,9 @@ FUNC KiXmmException
     jge KiXmmExit
 
     /* Dispatch the exception */
-    DispatchException eax, 3, 0, 0, 0
+    DispatchException eax, 2, 0, [rbp+KTRAP_FRAME_MxCsr], 0
+
+    // FIXME: STATUS_FLOAT_MULTIPLE_TRAPS / STATUS_FLOAT_MULTIPLE_FAULTS
 
 KiXmmExit:
     /* Return */

Reply via email to