kernel/x86: Determine math/SIMD exception cause in exception handler.
Fixes a TODO. Change-Id: I75e7f05bd72f1500234a7b43ed9da01d3a61ecf2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9082 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Jérôme Duval <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
4c76039f6f
commit
bdb6d7db1a
@@ -28,6 +28,7 @@
|
|||||||
#include <arch/x86/msi.h>
|
#include <arch/x86/msi.h>
|
||||||
#include <arch/x86/msi_priv.h>
|
#include <arch/x86/msi_priv.h>
|
||||||
|
|
||||||
|
#include <fenv.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// interrupt controllers
|
// interrupt controllers
|
||||||
@@ -157,13 +158,39 @@ x86_unexpected_exception(iframe* frame)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 16: // x87 FPU Floating-Point Error (#MF)
|
case 16: // x87 FPU Floating-Point Error (#MF)
|
||||||
|
case 19: // SIMD Floating-Point Exception (#XF)
|
||||||
|
{
|
||||||
type = B_FLOATING_POINT_EXCEPTION;
|
type = B_FLOATING_POINT_EXCEPTION;
|
||||||
signalNumber = SIGFPE;
|
signalNumber = SIGFPE;
|
||||||
signalCode = FPE_FLTDIV;
|
signalCode = FPE_FLTINV;
|
||||||
// TODO: Determine the correct cause via the FPU status
|
|
||||||
// register!
|
|
||||||
signalAddress = frame->ip;
|
signalAddress = frame->ip;
|
||||||
|
|
||||||
|
uint32 status = 0;
|
||||||
|
if (frame->vector == 19) {
|
||||||
|
// MXCSR is only available on SSE, however exception 19 should only
|
||||||
|
// ever occur if the processor has SSE anyway and OSXMMEXCPT is set.
|
||||||
|
__stmxcsr(&status);
|
||||||
|
} else {
|
||||||
|
uint16 fsw = 0;
|
||||||
|
__fnstsw(&fsw);
|
||||||
|
status = fsw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the real cause of the exception, if possible.
|
||||||
|
if ((status & FE_INVALID) != 0)
|
||||||
|
signalCode = FPE_FLTINV;
|
||||||
|
else if ((status & FE_DENORMAL) != 0)
|
||||||
|
signalCode = FPE_FLTUND;
|
||||||
|
else if ((status & FE_DIVBYZERO) != 0)
|
||||||
|
signalCode = FPE_FLTDIV;
|
||||||
|
else if ((status & FE_OVERFLOW) != 0)
|
||||||
|
signalCode = FPE_FLTOVF;
|
||||||
|
else if ((status & FE_UNDERFLOW) != 0)
|
||||||
|
signalCode = FPE_FLTUND;
|
||||||
|
else if ((status & FE_INEXACT) != 0)
|
||||||
|
signalCode = FPE_FLTRES;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 17: // Alignment Check Exception (#AC)
|
case 17: // Alignment Check Exception (#AC)
|
||||||
type = B_ALIGNMENT_EXCEPTION;
|
type = B_ALIGNMENT_EXCEPTION;
|
||||||
@@ -174,14 +201,6 @@ x86_unexpected_exception(iframe* frame)
|
|||||||
signalError = EFAULT;
|
signalError = EFAULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 19: // SIMD Floating-Point Exception (#XF)
|
|
||||||
type = B_FLOATING_POINT_EXCEPTION;
|
|
||||||
signalNumber = SIGFPE;
|
|
||||||
signalCode = FPE_FLTDIV;
|
|
||||||
// TODO: Determine the correct cause via the MXCSR register!
|
|
||||||
signalAddress = frame->ip;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
x86_invalid_exception(frame);
|
x86_invalid_exception(frame);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user