arm64: Enable the floating-point exception traps
To enable it user-space needs to call feenableexcept(). FPE_FLTIDO has been added as the IDF bit can't be mapped to any existing FPE code. Reviewed by: andrew@ Differential revision: https://reviews.freebsd.org/D35247 MFC after: 2 weeks
This commit is contained in:
parent
2cd662064a
commit
6e2caba7a1
@ -411,6 +411,29 @@ print_registers(struct trapframe *frame)
|
|||||||
printf("spsr: %8x\n", frame->tf_spsr);
|
printf("spsr: %8x\n", frame->tf_spsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VFP
|
||||||
|
static void
|
||||||
|
fpe_trap(struct thread *td, void *addr, uint32_t exception)
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
|
||||||
|
code = FPE_FLTIDO;
|
||||||
|
if ((exception & ISS_FP_TFV) != 0) {
|
||||||
|
if ((exception & ISS_FP_IOF) != 0)
|
||||||
|
code = FPE_FLTINV;
|
||||||
|
else if ((exception & ISS_FP_DZF) != 0)
|
||||||
|
code = FPE_FLTDIV;
|
||||||
|
else if ((exception & ISS_FP_OFF) != 0)
|
||||||
|
code = FPE_FLTOVF;
|
||||||
|
else if ((exception & ISS_FP_UFF) != 0)
|
||||||
|
code = FPE_FLTUND;
|
||||||
|
else if ((exception & ISS_FP_IXF) != 0)
|
||||||
|
code = FPE_FLTRES;
|
||||||
|
}
|
||||||
|
call_trapsignal(td, SIGFPE, code, addr, exception);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
do_el1h_sync(struct thread *td, struct trapframe *frame)
|
do_el1h_sync(struct thread *td, struct trapframe *frame)
|
||||||
{
|
{
|
||||||
@ -556,11 +579,18 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
|
|||||||
|
|
||||||
switch (exception) {
|
switch (exception) {
|
||||||
case EXCP_FP_SIMD:
|
case EXCP_FP_SIMD:
|
||||||
case EXCP_TRAP_FP:
|
|
||||||
#ifdef VFP
|
#ifdef VFP
|
||||||
vfp_restore_state();
|
vfp_restore_state();
|
||||||
#else
|
#else
|
||||||
panic("VFP exception in userland");
|
panic("VFP exception in userland");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case EXCP_TRAP_FP:
|
||||||
|
#ifdef VFP
|
||||||
|
fpe_trap(td, (void *)frame->tf_elr, esr);
|
||||||
|
userret(td, frame);
|
||||||
|
#else
|
||||||
|
panic("VFP exception in userland");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case EXCP_SVC32:
|
case EXCP_SVC32:
|
||||||
|
@ -265,6 +265,14 @@
|
|||||||
|
|
||||||
/* ESR_ELx */
|
/* ESR_ELx */
|
||||||
#define ESR_ELx_ISS_MASK 0x01ffffff
|
#define ESR_ELx_ISS_MASK 0x01ffffff
|
||||||
|
#define ISS_FP_TFV_SHIFT 23
|
||||||
|
#define ISS_FP_TFV (0x01 << ISS_FP_TFV_SHIFT)
|
||||||
|
#define ISS_FP_IOF 0x01
|
||||||
|
#define ISS_FP_DZF 0x02
|
||||||
|
#define ISS_FP_OFF 0x04
|
||||||
|
#define ISS_FP_UFF 0x08
|
||||||
|
#define ISS_FP_IXF 0x10
|
||||||
|
#define ISS_FP_IDF 0x80
|
||||||
#define ISS_INSN_FnV (0x01 << 10)
|
#define ISS_INSN_FnV (0x01 << 10)
|
||||||
#define ISS_INSN_EA (0x01 << 9)
|
#define ISS_INSN_EA (0x01 << 9)
|
||||||
#define ISS_INSN_S1PTW (0x01 << 7)
|
#define ISS_INSN_S1PTW (0x01 << 7)
|
||||||
|
@ -339,6 +339,7 @@ struct siginfo32 {
|
|||||||
#define FPE_FLTRES 6 /* Floating point inexact result. */
|
#define FPE_FLTRES 6 /* Floating point inexact result. */
|
||||||
#define FPE_FLTINV 7 /* Invalid floating point operation. */
|
#define FPE_FLTINV 7 /* Invalid floating point operation. */
|
||||||
#define FPE_FLTSUB 8 /* Subscript out of range. */
|
#define FPE_FLTSUB 8 /* Subscript out of range. */
|
||||||
|
#define FPE_FLTIDO 9 /* Input denormal operation */
|
||||||
|
|
||||||
/* codes for SIGTRAP */
|
/* codes for SIGTRAP */
|
||||||
#define TRAP_BRKPT 1 /* Process breakpoint. */
|
#define TRAP_BRKPT 1 /* Process breakpoint. */
|
||||||
|
Loading…
Reference in New Issue
Block a user