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 */